SlideShare a Scribd company logo
AsyncTask アンチパターン 
2014-12-04 Android アンチパターン勉強会 
黒川 洋 / @hydrakecat
背景 
非同期処理で AsyncTask が使われているコードをよく見か 
けるが、けっこう気軽に使われている 
非同期処理の問題は起きるかどうかがタイミング次第なこ 
とが多いので、再現や解決が困難なバグを生む 
ネットに転がっている情報や解決方法は間違っていること 
が多い印象 
非同期処理は、人間にはまだ早すぎる...
ネタ元参考文献 
Processes and Threads | Android Developers 
Handling Runtime Changes | Android Developers 
Efficient Android Threading (Anders Goransson) 
Android の非同期処理についての解説。Thread や Looper か 
ら解説してあって勉強になる。
事前知識(おさらい) 
Android では View の操作を UI スレッド(メインスレッ 
ド)からしかできない 
重い処理を UI スレッドで行うと、ユーザーからはアプリが 
反応しないように見える 
5秒以上応答がないと ANR (Application Not Responding) エ 
ラーが表示される 
描画に関係しない重い処理はバックグラウンドで処理する
Android の非同期処理 
Basic Thread 
HandlerThread 
Executor 
AsyncTask 
Services 
AsyncQueryHandler 
Loader
Android の非同期処理 
Basic Thread 
HandlerThread 
Executor 
AsyncTask 
Services 
AsyncQueryHandler 
Loader
AsyncTask とは 
http://developer.android.com/reference/android/os/AsyncTask.html 
バックグラウンド処理を行って結果を UI スレッドに渡すた 
めのクラス。 
Thread や Handler のヘルパークラス。 
基本的には数秒程度の処理を行うのに使うもので、それ以 
上の処理を行いたい場合は、Executor などの使用が推奨さ 
れている。 
非常によく使われている。というか、非同期処理は、一般的 
に AsyncTask がむやみに使われていない印象。
AsyncTask の罠 (その1) 
@Override 
public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
... 
new AsyncTask<Void, String, Void>(){ 
@Override 
protected void onPreExecute() { 
super.onPreExecute(); 
mProgressDialog.show(); 
} 
@Override 
protected String doInBackground(Void... value) { 
try { 
Thread.sleep(15000); 
} catch (InterruptedException e) { 
} 
return "AsyncTask Done"; 
} 
@Override 
protected void onPostExecute(String result) { 
mProgressDialog.dismiss(); 
mTextView.setText(result); 
} 
}.execute();
IllegalArgumentException 
画面回転などで Configuration Chage が発生すると、Activity 
の再生成が行われる 
→ その際に Fragment が detach されるので 
mProgressDialog.dismiss() で 
IllegalArgumentException が発生する。 
ウェブの記事では、画面固定を推奨しているものもあるが、 
画面回転以外(キーボードの表示とか)にも Configuration 
Change は起き得るので、これではダメ。
IllegalArgumentException の 
とりあえずの対処 
onDestroy 時にダイアログを閉じて null にしておく 
@Override 
public void onCreate(Bundle savedInstanceState) { 
... 
new AsyncTask<Void, Void, String>(){ 
... 
@Override 
protected void onPostExecute(String result) { 
if (mProgressDialog != null) { 
mProgressDialog.dismiss(); 
} 
if (mTextView != null) { 
mTextView.setText(result); 
} 
} 
}.execute(); 
} 
@Override 
public void onDestroy() { 
if (mProgressDialog != null && mProgressDialog.isShowing()) { 
というか、mProgressDialog.ガイドライdismiss(); 
ン通り、ProgressDialog は使わない! 
} 
mProgressDialog = null; 
}
問題点 
Configuration change が起きて、Activity が再生成になる 
と、AsyncTask の結果は捨てられることになる 
それが嫌なら、Thread や AsyncTaskLoader などを使っ 
て、再生成された Activity にスレッドをアタッチする
AsyncTask の罠 (その2) 
Fragment#getActivity() が null になることがある 
画面回転などで Configuration Chage が発生すると、Fragment 
が detach されてしまう 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
Bundle savedInstanceState) { 
... 
new AsyncTask<Void, Void, String[]>(){ 
... 
@Override 
protected void onPostExecute(String[] result) { 
mAdapter = new ArrayAdapter<String>(getActivity(), R.layout.listrow, result); 
mListView.setAdapter(mAdapter); 
} 
}.execute(); 
}
NullPointerException の対処 
Fragment#isAdded()で確認する 
あと、個人的には mAdapter はコールバックで作らない方 
が好き 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
Bundle savedInstanceState) { 
... 
new AsyncTask<Void, Void, String[]>(){ 
... 
@Override 
protected void onPostExecute(String[] result) { 
if (isAdded() && mAdapter != null) { 
mAdapter.addAll(Arrays.asList(result)); 
mAdapter.notifyDatasetChanged(); 
} 
} 
}.execute(); 
}
AsyncTask の罠 (その3) 
長い処理を行うとメモリリークの可能性がある 
task = new AsyncTask<Void, String, Void>(){ 
... 
}.execute(); 
non-static な内部クラスは暗黙に親オブジェクト(Activity 
オブジェクト)への参照を持っている 
AsyncTask が内部的に利用しているスレッドが生きている 
限り、このオブジェクトは GC されない 
出典: Efficient Android Threading
メモリリークの対処法 
non-static な内部クラスにせず、static な内部クラスにする 
か別クラスにする 
Activity#onDestory() 時に Activity への参照を破棄し 
て AsyncTask#cancel() を呼ぶ 
もしくは、Activity への参照を弱参照(Weak Reference) 
にする 
@Override public void onCreate(Bundle savedInstanceState) { 
... 
mTask = new MyTask(this); 
mTask.execute(); 
} 
@Override protected void onDestroy () { 
super.onDestroy(); 
mTask.setActivity(null); 
mTask.cancel(true); 
} 
private static class MyTask extends AsyncTask<String, Bitmap, Void> { 
... 
}
メモリリークの対処法(再びAsyncTask#cancel(false)は、isCanceledをtrueに 
セットして、実行中のタスクが終わるまで待機する。 
AsyncTask#cancel(true)にしても、即座にスレッドが 
終了することを保証しない。 
private static class MyTask extends AsyncTask<Void, Void, String> { 
@Override 
protected String doInBackground(Void... params) { 
for (int i=0; i<NUM_TASKS; i++) { 
if (this.isCancelled()) { 
return null; 
} else { 
try { 
// Do any task 
} catch (InterruptedException iex) { 
// the blocking method throws an InterruptedException 
return null; 
} 
} 
} 
return "AsyncTask Done"; 
} 
}
AsyncTask の罠 (その4) 
AsyncTask を複数実行したときに、逐次実行される 
(sequential)か、同時実行される(concurrent)かは、呼 
び出し方、APIレベルで変わる 
実行環境はアプリケーション全体で同一(ある Service の 
AsyncTask が別 Activity の AsyncTask をブロックしうる) 
API targetSdkVersion execute executeOnExecutor 
1-3 Any Sequential Not available 
4-10 Any Concurrent Not available 
11-12 Any Concurrent Sequential/Concurrent (customizable) 
13+ <13 Concurrent Sequential/Concurrent (customizable) 
13+ ≥13 Sequential Sequential/Concurrent (customizable)
API レベルに関わらず処理を 
同じにするには 
逐次実行 
2.3系をサポートする限り無理です。AsyncTaskを諦めてく 
ださい。 
同時実行 
targetSdkVersion を < 13 にするか、API レベルによって処理 
を変える必要があります。 
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR1) { 
new MyAsyncTask().execute(); 
} else { 
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
}
まとめ 
オススメの AsyncTask の使い方 
軽い処理だけにしておく 
non-static な inner class にしない 
Activity#onDestroy()で、キャンセルと Activity の参 
照の解放を忘れずに行う 
場合に応じて AsyncTaskLoader 、 Executor 、 
HandlerThread の利用も検討する

More Related Content

What's hot

DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
JustSystems Corporation
 
Kotlinアンチパターン
KotlinアンチパターンKotlinアンチパターン
Kotlinアンチパターン
Recruit Lifestyle Co., Ltd.
 
テストコードの DRY と DAMP
テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMP
Yusuke Kagata
 
はじめての ASP.NET MVC
はじめての ASP.NET MVCはじめての ASP.NET MVC
はじめての ASP.NET MVC
jz5 MATSUE
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
Hiroshi Ito
 
40歳過ぎてもエンジニアでいるためにやっていること
40歳過ぎてもエンジニアでいるためにやっていること40歳過ぎてもエンジニアでいるためにやっていること
40歳過ぎてもエンジニアでいるためにやっていること
onozaty
 
ドメイン駆動設計の基礎知識:設計のスタイル、開発のスタイル
ドメイン駆動設計の基礎知識:設計のスタイル、開発のスタイルドメイン駆動設計の基礎知識:設計のスタイル、開発のスタイル
ドメイン駆動設計の基礎知識:設計のスタイル、開発のスタイル
増田 亨
 
SQLアンチパターン~スパゲッティクエリ
SQLアンチパターン~スパゲッティクエリSQLアンチパターン~スパゲッティクエリ
SQLアンチパターン~スパゲッティクエリ
Itabashi Masayuki
 
Lean coffee
Lean coffeeLean coffee
Lean coffee
Takeshi Arai
 
go generate 完全入門
go generate 完全入門go generate 完全入門
go generate 完全入門
yaegashi
 
ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方
増田 亨
 
ストーリーポイントで見積もるということ
ストーリーポイントで見積もるということストーリーポイントで見積もるということ
ストーリーポイントで見積もるということ
Yagi Natsuki
 
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
「関心の分離」と「疎結合」   ソフトウェアアーキテクチャのひとかけら「関心の分離」と「疎結合」   ソフトウェアアーキテクチャのひとかけら
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
Atsushi Nakamura
 
Akkaとは。アクターモデル とは。
Akkaとは。アクターモデル とは。Akkaとは。アクターモデル とは。
Akkaとは。アクターモデル とは。
Kenjiro Kubota
 
Kotlinミニアンチパターン
KotlinミニアンチパターンKotlinミニアンチパターン
Kotlinミニアンチパターン
Recruit Lifestyle Co., Ltd.
 
データローダについてちょっと詳しくなる
データローダについてちょっと詳しくなるデータローダについてちょっと詳しくなる
データローダについてちょっと詳しくなる
Junko Nakayama
 
20170527 inside .NET Core on Linux
20170527 inside .NET Core on Linux20170527 inside .NET Core on Linux
20170527 inside .NET Core on Linux
Takayoshi Tanaka
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
yoku0825
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
Takaaki Suzuki
 

What's hot (20)

DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
 
Kotlinアンチパターン
KotlinアンチパターンKotlinアンチパターン
Kotlinアンチパターン
 
テストコードの DRY と DAMP
テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMP
 
はじめての ASP.NET MVC
はじめての ASP.NET MVCはじめての ASP.NET MVC
はじめての ASP.NET MVC
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
 
40歳過ぎてもエンジニアでいるためにやっていること
40歳過ぎてもエンジニアでいるためにやっていること40歳過ぎてもエンジニアでいるためにやっていること
40歳過ぎてもエンジニアでいるためにやっていること
 
ドメイン駆動設計の基礎知識:設計のスタイル、開発のスタイル
ドメイン駆動設計の基礎知識:設計のスタイル、開発のスタイルドメイン駆動設計の基礎知識:設計のスタイル、開発のスタイル
ドメイン駆動設計の基礎知識:設計のスタイル、開発のスタイル
 
SQLアンチパターン~スパゲッティクエリ
SQLアンチパターン~スパゲッティクエリSQLアンチパターン~スパゲッティクエリ
SQLアンチパターン~スパゲッティクエリ
 
Lean coffee
Lean coffeeLean coffee
Lean coffee
 
go generate 完全入門
go generate 完全入門go generate 完全入門
go generate 完全入門
 
ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方
 
ストーリーポイントで見積もるということ
ストーリーポイントで見積もるということストーリーポイントで見積もるということ
ストーリーポイントで見積もるということ
 
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
「関心の分離」と「疎結合」   ソフトウェアアーキテクチャのひとかけら「関心の分離」と「疎結合」   ソフトウェアアーキテクチャのひとかけら
「関心の分離」と「疎結合」 ソフトウェアアーキテクチャのひとかけら
 
Java8でRDBMS作ったよ
Java8でRDBMS作ったよJava8でRDBMS作ったよ
Java8でRDBMS作ったよ
 
Akkaとは。アクターモデル とは。
Akkaとは。アクターモデル とは。Akkaとは。アクターモデル とは。
Akkaとは。アクターモデル とは。
 
Kotlinミニアンチパターン
KotlinミニアンチパターンKotlinミニアンチパターン
Kotlinミニアンチパターン
 
データローダについてちょっと詳しくなる
データローダについてちょっと詳しくなるデータローダについてちょっと詳しくなる
データローダについてちょっと詳しくなる
 
20170527 inside .NET Core on Linux
20170527 inside .NET Core on Linux20170527 inside .NET Core on Linux
20170527 inside .NET Core on Linux
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 

Similar to AsyncTask アンチパターン

ASP.NETを利用したAJAX開発の応用
ASP.NETを利用したAJAX開発の応用ASP.NETを利用したAJAX開発の応用
ASP.NETを利用したAJAX開発の応用
Sho Okada
 
おいしいFragment #antama_ws
おいしいFragment #antama_wsおいしいFragment #antama_ws
おいしいFragment #antama_wsTakahiro Yoshimura
 
Weeyble async 181009_tukky
Weeyble async 181009_tukkyWeeyble async 181009_tukky
Weeyble async 181009_tukky
shotaueda3
 
Androidの通信周りのコーディングについて
Androidの通信周りのコーディングについてAndroidの通信周りのコーディングについて
Androidの通信周りのコーディングについてShoichi Takagi
 
Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.
Yuki Higuchi
 
ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】株式会社ランチェスター
 
Sencha ug3 siesta_share
Sencha ug3 siesta_shareSencha ug3 siesta_share
Sencha ug3 siesta_share
久司 中村
 
GroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackGroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hack
Takahiro Yoshimura
 
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
Satoshi Mimura
 
20130924 Picomon CRH勉強会
20130924 Picomon CRH勉強会20130924 Picomon CRH勉強会
20130924 Picomon CRH勉強会
Yukihiro Kitazawa
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
YujiSoftware
 
React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門
spring_raining
 
Rx java x retrofit
Rx java x retrofitRx java x retrofit
Rx java x retrofit
Shun Nakahara
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
Kohsuke Yuasa
 
Unit testing JavaScript with JUnit/JavaFX
Unit testing JavaScript with JUnit/JavaFXUnit testing JavaScript with JUnit/JavaFX
Unit testing JavaScript with JUnit/JavaFX
Shinya Mochida
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive Extensions
Yoshifumi Kawai
 
ありえるえりあ勉強会@五反田~テスト編~ Part3
ありえるえりあ勉強会@五反田~テスト編~ Part3ありえるえりあ勉強会@五反田~テスト編~ Part3
ありえるえりあ勉強会@五反田~テスト編~ Part3Tomoyuki Sato
 
Project Loom - 限定継続と軽量スレッド -
Project Loom - 限定継続と軽量スレッド - Project Loom - 限定継続と軽量スレッド -
Project Loom - 限定継続と軽量スレッド -
Yuichi Sakuraba
 
マーブル図で怖くないRxJS
マーブル図で怖くないRxJSマーブル図で怖くないRxJS
マーブル図で怖くないRxJS
bitbank, Inc. Tokyo, Japan
 

Similar to AsyncTask アンチパターン (20)

ASP.NETを利用したAJAX開発の応用
ASP.NETを利用したAJAX開発の応用ASP.NETを利用したAJAX開発の応用
ASP.NETを利用したAJAX開発の応用
 
おいしいFragment #antama_ws
おいしいFragment #antama_wsおいしいFragment #antama_ws
おいしいFragment #antama_ws
 
Weeyble async 181009_tukky
Weeyble async 181009_tukkyWeeyble async 181009_tukky
Weeyble async 181009_tukky
 
Androidの通信周りのコーディングについて
Androidの通信周りのコーディングについてAndroidの通信周りのコーディングについて
Androidの通信周りのコーディングについて
 
Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.
 
ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】
 
Sencha ug3 siesta_share
Sencha ug3 siesta_shareSencha ug3 siesta_share
Sencha ug3 siesta_share
 
GroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackGroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hack
 
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
 
About Jobs
About JobsAbout Jobs
About Jobs
 
20130924 Picomon CRH勉強会
20130924 Picomon CRH勉強会20130924 Picomon CRH勉強会
20130924 Picomon CRH勉強会
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
 
React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門
 
Rx java x retrofit
Rx java x retrofitRx java x retrofit
Rx java x retrofit
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
Unit testing JavaScript with JUnit/JavaFX
Unit testing JavaScript with JUnit/JavaFXUnit testing JavaScript with JUnit/JavaFX
Unit testing JavaScript with JUnit/JavaFX
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive Extensions
 
ありえるえりあ勉強会@五反田~テスト編~ Part3
ありえるえりあ勉強会@五反田~テスト編~ Part3ありえるえりあ勉強会@五反田~テスト編~ Part3
ありえるえりあ勉強会@五反田~テスト編~ Part3
 
Project Loom - 限定継続と軽量スレッド -
Project Loom - 限定継続と軽量スレッド - Project Loom - 限定継続と軽量スレッド -
Project Loom - 限定継続と軽量スレッド -
 
マーブル図で怖くないRxJS
マーブル図で怖くないRxJSマーブル図で怖くないRxJS
マーブル図で怖くないRxJS
 

Recently uploaded

【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
harmonylab
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
Matsushita Laboratory
 
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdfFIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LBカタログ
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LBカタログLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LBカタログ
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LBカタログ
CRI Japan, Inc.
 
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
NTT DATA Technology & Innovation
 
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
Fukuoka Institute of Technology
 
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdfFIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance
 
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
yassun7010
 
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdfFIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdfFIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance
 
【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow
Sony - Neural Network Libraries
 
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
iPride Co., Ltd.
 
CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料
Yuuitirou528 default
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
Toru Tamaki
 
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdfFIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance
 

Recently uploaded (15)

【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
 
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdfFIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LBカタログ
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LBカタログLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LBカタログ
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LBカタログ
 
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
 
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
 
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdfFIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
 
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
 
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdfFIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdf
 
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdfFIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
 
【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow
 
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
 
CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
 
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdfFIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
 

AsyncTask アンチパターン

  • 1. AsyncTask アンチパターン 2014-12-04 Android アンチパターン勉強会 黒川 洋 / @hydrakecat
  • 2. 背景 非同期処理で AsyncTask が使われているコードをよく見か けるが、けっこう気軽に使われている 非同期処理の問題は起きるかどうかがタイミング次第なこ とが多いので、再現や解決が困難なバグを生む ネットに転がっている情報や解決方法は間違っていること が多い印象 非同期処理は、人間にはまだ早すぎる...
  • 3. ネタ元参考文献 Processes and Threads | Android Developers Handling Runtime Changes | Android Developers Efficient Android Threading (Anders Goransson) Android の非同期処理についての解説。Thread や Looper か ら解説してあって勉強になる。
  • 4. 事前知識(おさらい) Android では View の操作を UI スレッド(メインスレッ ド)からしかできない 重い処理を UI スレッドで行うと、ユーザーからはアプリが 反応しないように見える 5秒以上応答がないと ANR (Application Not Responding) エ ラーが表示される 描画に関係しない重い処理はバックグラウンドで処理する
  • 5. Android の非同期処理 Basic Thread HandlerThread Executor AsyncTask Services AsyncQueryHandler Loader
  • 6. Android の非同期処理 Basic Thread HandlerThread Executor AsyncTask Services AsyncQueryHandler Loader
  • 7. AsyncTask とは http://developer.android.com/reference/android/os/AsyncTask.html バックグラウンド処理を行って結果を UI スレッドに渡すた めのクラス。 Thread や Handler のヘルパークラス。 基本的には数秒程度の処理を行うのに使うもので、それ以 上の処理を行いたい場合は、Executor などの使用が推奨さ れている。 非常によく使われている。というか、非同期処理は、一般的 に AsyncTask がむやみに使われていない印象。
  • 8. AsyncTask の罠 (その1) @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... new AsyncTask<Void, String, Void>(){ @Override protected void onPreExecute() { super.onPreExecute(); mProgressDialog.show(); } @Override protected String doInBackground(Void... value) { try { Thread.sleep(15000); } catch (InterruptedException e) { } return "AsyncTask Done"; } @Override protected void onPostExecute(String result) { mProgressDialog.dismiss(); mTextView.setText(result); } }.execute();
  • 9. IllegalArgumentException 画面回転などで Configuration Chage が発生すると、Activity の再生成が行われる → その際に Fragment が detach されるので mProgressDialog.dismiss() で IllegalArgumentException が発生する。 ウェブの記事では、画面固定を推奨しているものもあるが、 画面回転以外(キーボードの表示とか)にも Configuration Change は起き得るので、これではダメ。
  • 10. IllegalArgumentException の とりあえずの対処 onDestroy 時にダイアログを閉じて null にしておく @Override public void onCreate(Bundle savedInstanceState) { ... new AsyncTask<Void, Void, String>(){ ... @Override protected void onPostExecute(String result) { if (mProgressDialog != null) { mProgressDialog.dismiss(); } if (mTextView != null) { mTextView.setText(result); } } }.execute(); } @Override public void onDestroy() { if (mProgressDialog != null && mProgressDialog.isShowing()) { というか、mProgressDialog.ガイドライdismiss(); ン通り、ProgressDialog は使わない! } mProgressDialog = null; }
  • 11. 問題点 Configuration change が起きて、Activity が再生成になる と、AsyncTask の結果は捨てられることになる それが嫌なら、Thread や AsyncTaskLoader などを使っ て、再生成された Activity にスレッドをアタッチする
  • 12. AsyncTask の罠 (その2) Fragment#getActivity() が null になることがある 画面回転などで Configuration Chage が発生すると、Fragment が detach されてしまう @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... new AsyncTask<Void, Void, String[]>(){ ... @Override protected void onPostExecute(String[] result) { mAdapter = new ArrayAdapter<String>(getActivity(), R.layout.listrow, result); mListView.setAdapter(mAdapter); } }.execute(); }
  • 13. NullPointerException の対処 Fragment#isAdded()で確認する あと、個人的には mAdapter はコールバックで作らない方 が好き @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... new AsyncTask<Void, Void, String[]>(){ ... @Override protected void onPostExecute(String[] result) { if (isAdded() && mAdapter != null) { mAdapter.addAll(Arrays.asList(result)); mAdapter.notifyDatasetChanged(); } } }.execute(); }
  • 14. AsyncTask の罠 (その3) 長い処理を行うとメモリリークの可能性がある task = new AsyncTask<Void, String, Void>(){ ... }.execute(); non-static な内部クラスは暗黙に親オブジェクト(Activity オブジェクト)への参照を持っている AsyncTask が内部的に利用しているスレッドが生きている 限り、このオブジェクトは GC されない 出典: Efficient Android Threading
  • 15. メモリリークの対処法 non-static な内部クラスにせず、static な内部クラスにする か別クラスにする Activity#onDestory() 時に Activity への参照を破棄し て AsyncTask#cancel() を呼ぶ もしくは、Activity への参照を弱参照(Weak Reference) にする @Override public void onCreate(Bundle savedInstanceState) { ... mTask = new MyTask(this); mTask.execute(); } @Override protected void onDestroy () { super.onDestroy(); mTask.setActivity(null); mTask.cancel(true); } private static class MyTask extends AsyncTask<String, Bitmap, Void> { ... }
  • 16. メモリリークの対処法(再びAsyncTask#cancel(false)は、isCanceledをtrueに セットして、実行中のタスクが終わるまで待機する。 AsyncTask#cancel(true)にしても、即座にスレッドが 終了することを保証しない。 private static class MyTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... params) { for (int i=0; i<NUM_TASKS; i++) { if (this.isCancelled()) { return null; } else { try { // Do any task } catch (InterruptedException iex) { // the blocking method throws an InterruptedException return null; } } } return "AsyncTask Done"; } }
  • 17. AsyncTask の罠 (その4) AsyncTask を複数実行したときに、逐次実行される (sequential)か、同時実行される(concurrent)かは、呼 び出し方、APIレベルで変わる 実行環境はアプリケーション全体で同一(ある Service の AsyncTask が別 Activity の AsyncTask をブロックしうる) API targetSdkVersion execute executeOnExecutor 1-3 Any Sequential Not available 4-10 Any Concurrent Not available 11-12 Any Concurrent Sequential/Concurrent (customizable) 13+ <13 Concurrent Sequential/Concurrent (customizable) 13+ ≥13 Sequential Sequential/Concurrent (customizable)
  • 18. API レベルに関わらず処理を 同じにするには 逐次実行 2.3系をサポートする限り無理です。AsyncTaskを諦めてく ださい。 同時実行 targetSdkVersion を < 13 にするか、API レベルによって処理 を変える必要があります。 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR1) { new MyAsyncTask().execute(); } else { new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }
  • 19. まとめ オススメの AsyncTask の使い方 軽い処理だけにしておく non-static な inner class にしない Activity#onDestroy()で、キャンセルと Activity の参 照の解放を忘れずに行う 場合に応じて AsyncTaskLoader 、 Executor 、 HandlerThread の利用も検討する