ハンドラーとAsyncTask


128

ハンドラーではなくAsyncTaskをいつ選択するのか混乱しています。UIを更新するn秒ごとに実行するコードがあるとします。なぜどちらを選ぶのですか?


1
これは、AsyncTaskLoadersでさらに複雑になっています。詳細については、stackoverflow.com / q / 7120813/969325をご覧ください。
Warpzit 2013

回答:


75

IMO、AsyncTaskは、低レベルの詳細(スレッド、メッセージループなど)をあまり気にすることなく、Androidアプリでバックグラウンド処理を実現する便利で使いやすい方法を提供するために作成されました。タスクをスケジュールし、必要に応じてUIを簡単に更新するのに役立つコールバックメソッドを提供します。

ただし、AsyncTaskを使用する場合、開発者はその制限を受け入れていることに注意することが重要です。これは、クラスの作成者が行った設計上の決定が原因です。たとえば、最近AsyncTasksを使用してスケジュールできるジョブの数に制限があることがわかりました。

ハンドラーは2つの中でより透過的で、おそらくより多くの自由を与えます。したがって、より詳細な制御が必要な場合は、ハンドラを選択します。それ以外の場合は、AsynTaskが正常に機能します。


そのとおり。プロジェクトのすべてのバックグラウンドオペレーションにAsyncTasksを使用していました。ある時点で、最大ジョブ数の制限に達し始めたので、私のタスクは別のタスクが終了した後にのみ開始されました。結局、asynctasksの使用を停止し、その制限に達しないように、すべての構造を変更する必要がありました。
tbraun 2013

5
Honeycomb以降、AsyncTasks1つのスレッドで実行されるため、並列処理は行われません。並列Executor実装でそれらを実行することもできます。
MrSnowflake 2013年

63

私の経験則は:

  • リストに表示するデータをダウンロードするなど、UIに関連する分離された処理を行う場合は、を使用してくださいAsyncTask

  • ダウンロード時に表示されるImageViews(サムネイルのダウンロードなど)複数の画像をダウンロードするなど、複数の繰り返しタスクを実行している場合は、でタスクキューを使用しますHandler


ハンドラーはAPIレベル1にあり、ASYNCTASKはAPIレベル3にあります。何らかの理由で非推奨になりますか?... 2.2&2.3に旧バージョンからアプリケーションを移植することに集中午前becaz
yokks

10
どちらもすぐには廃止されません。UIは基本的にハンドラーを中心に構築されているため、ハンドラーが廃止されることはありません。
alexanderblom

ローダーを使用して、UIが表示するデータをロードすべきではありませんか?
nbarraille、2014年

19

主に次の理由により、可能な場合は常にAsyncTaskの使用を避けてください。

  • ThreadPoolベースと最大サイズがシステムによって設定されているため、AsyncTaskの実行は保証されていません。非同期タスクを作成しすぎると、最終的に破棄されます。

  • AsyncTaskは、アクティビティのライフサイクルに応じて、実行中であっても自動的に終了することができ、それを制御することはできません

  • onPostExecuteなどのUIスレッドで実行されているAsyncTaskメソッドは、それが参照しているアクティビティが表示されなくなった場合、または方向が変更された後など、別のレイアウト状態にある場合に実行できます。

結論として、AsyncTaskのUIThreadリンクメソッドを使用しないでください。これが主な利点です!!! さらに、doInBackgroundで重要でない作業のみを行う必要があります。この問題の詳細については、このスレッドをご覧ください。

AsyncTaskは本当に概念的に欠陥があるのですか、それとも何か不足していますか?

結論として、上記のいずれかの問題が懸念される場合は、AsyncTaskの代わりにIntentServices、HandlerThread、またはThreadPoolExecutorを使用することをお勧めします。もちろん、より多くの作業が必要になりますが、アプリケーションはより安全になります。


ええ、私は多くの時間を費やしてAsyncTasksの多くの使用法を後悔しました。彼らは素晴らしいように見えますが...非常に多くの問題!
SMBiggs 2015

6
あなたのポイントに対して非常に強く投稿して申し訳ありませんが、私はあなたの貧弱なスタイルの効果をアンドロイドに与えることはできません。ポイント1。それほど多くのスレッドを実行してはいけません。これに遭遇した場合、あなたのアーキテクチャはfoobarです。ポイント2.一体どうやって..わかりました、はい、Androidのすべてがガベージコレクターにとって無料のゲームです...一部の厳密なタスクの虐待的なケースでは、上記のような異常な動作のみが表示されます。ポイント3.失礼なことではなく、タスクの管理は初心者のスキルです。onPauseを呼び出すときにそれを強制終了するか、適切にデタッチしてアタッチします。
StarWind0

1
vogella.com/tutorials/AndroidBackgroundProcessing/article.htmlこれは、上記の問題なしにタスクを適切に実行する方法を学ぶために必要なすべてです(数百のタスクを噴出するようなものを実行していないと想定)
StarWind0

16

x秒ごとに計算を実行する場合はRunnable、をHandler(でpostDelayed())にスケジュールRunnableし、それを現在のUIスレッドで開始する必要があります。別のスレッドで開始する場合は、HandlerThreadを使用します。AsyncTaskの方が使いやすいですが、ハンドラに勝るものはありません。


7

ハンドラーは、アプリケーションのメインスレッドに関連付けられています。バックグラウンドスレッドからアプリのメインスレッドに送信されるメッセージと実行可能ファイルを処理およびスケジュールします。

AsyncTaskは、時間のかかる操作によってUIをブロックすることなくUIを更新するために、バックグラウンドスレッドを処理する簡単なメソッドを提供します。

答えは、どちらもバックグラウンドスレッドからUIを更新するために使用できるということです。違いは実行シナリオにあります。ハンドラーを使用して、遅延メッセージを投稿したり、メッセージを特定の順序でMessageQueueに送信したりすることを検討できます。

アプリのメインスレッドとバックグラウンドスレッドの間で簡単に便利な方法でパラメーターを(したがって、UIを更新して)交換する場合は、AsyncTaskの使用を検討してください。


3
別のスレッドに関連付けられた独自のハンドラーを作成できます。
Aleksejs Mjaliks 2012

ハンドラーは必ずしもメインスレッド(UIスレッド)に関連付けられていません。これは、インスタンス化されたスレッドに関連付けられており、このスレッドのメッセージキューに到着したMessageまたはRunnableを処理します。また、このスレッドメッセージキューにMessageオブジェクトとRunnableオブジェクトを送信できます。
azec-pdx 2014

2

AsyncTaskバックグラウンドの作業が完了した後、UIスレッドで何かを行うことを想定しています。また、実行できるのは1回だけです(この後のステータスはFINISHED、もう一度実行しようとすると例外が発生します)。また、それを使用する柔軟性はあまりありません。はい、THREAD_POOL_EXECUTOR並列実行に使用できますが、その努力は価値がないかもしれません。

Handlerランナブルとメッセージの処理以外は何も想定していません。また、何度でも実行できます。どのスレッドにアタッチする必要があるか、他のハンドラーと通信する方法を自由に決定できますHandlerThread。したがって、それははるかに柔軟性があり、繰り返し作業に適しています。

さまざまな種類のHandler例をここで確認してください。


0

彼らは尋ねられる最高のインタビューの質問です。 AsyncTask -UIスレッドのオフロードとバックグラウンドでのタスクの実行に使用されます。 ハンドラー -AndroidはUIとバックグラウンドスレッド間の直接通信手段を備えています。ハンドラーを使用してメッセージを送信するか、メッセージキューを介して実行可能にする必要があります。

したがって、AsyncTasksは、タスクをバックグラウンドで実行する必要がある場合に使用され、ハンドラーは、UIとバックグラウンドスレッド間の通信に使用されます。


0

doInBackground-基本的に別のスレッドで動作します。 onPostExecute -UIスレッドに結果を投稿し、内部的にメインスレッドのハンドラーにメッセージを送信しています。メインUIスレッドには既にルーパーとハンドラーが関連付けられています。

基本的に、バックグラウンドタスクを実行する必要がある場合は、AsyncTaskを使用します。しかし最終的には、UIで何かを更新する必要がある場合は、メインスレッドのハンドラーを使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.