2

誰かがAsyncTask内でrunOnUiThreadを使用しているのはおかしなことに聞こえます。どういうわけか、それは私のために働いていますが、それが許容可能で堅牢なアプローチであるかどうかを知りたいです。シナリオは次のとおりです。

ログインに成功した後、ユーザーが次の画面に表示されるアプリがあります。この新しい画面では、3つの異なる方法がWebサーバーからさまざまなタイプのデータをロードしています。これらのメソッドは次のとおりです。

  • getMembersForList():コミュニティメンバーのリストをロードし、リストビューに表示します。

  • getProfileData():ログインしているユーザーのプロファイルを読み込み、画面に名前や画像などを表示します。

  • getNotificationCounts:ユーザーの新しい通知の数をロードします。

私はそれに3つの異なるアプローチを適用しました:

(1) onCreateで3つのメソッドすべてを呼び出すだけです。つまり、どのメソッドにも排他的なスレッドは使用されていません。この場合、ログイン画面からこの画面への移行が非常に遅くなり、このアクティビティが表示される前にしばらくの間黒い画面が表示されます。

(2) UIスレッドでgetMembersForList()を呼び出し、排他的スレッドで他の2つのメソッドを呼び出します。この場合、遷移は速くなり、リストはすぐに表示されますが、このスレッドが他のスレッドのビュー(グローバルに宣言されているユーザー名、通知数などのTextViews)にアクセスできないというWrongThreadExceptionが発生するため、通知数やユーザー名などは表示されません)。これらのスレッドをAsyncTaskから開始した場合にも、同じことが起こります。

(3) UIスレッドでgetMembersForList()を呼び出してから、doInBackground()メソッド内の「runOnUiThread」で他の2つのメソッドが呼び出されているAsyncTaskを開始します。これにより、上記の両方の問題が解決されます。これで、画面の遷移が速くなり、WrongThread例外も発生しなくなりました。

これまでのところ、アプローチ-(3)は私にとってはうまく機能していますが、runOnUiThreadとAsyncTaskは完全に反対であるため、これが正しい方法であるかどうかはわかりません。誰かがこのシナリオについての私の疑問をクリアしてください。よろしくお願いします。

4

2 に答える 2

2

asyncTaskで3つの呼び出しをすべて実行し、バックグラウンドタスクが完了した後にAsyncTaskのpostExecute()でUIを更新することをお勧めします。postExecuteはUIthreadで実行されるため、UIthreadで実行するために明示的なものを呼び出す必要はありません。

于 2012-09-07T11:09:59.640 に答える
2

runOnUiThread()はい、このようなユースケースは、メソッドがそもそも存在する大きな理由です。アイデアは、バックグラウンドスレッド/AsyncTaskインスタンスがバックグラウンドで長い操作を実行できるようにし、結果が得られたときに(または任意の間隔で)インターフェイスを更新するために使用できる単純なフックを提供することです。結果のさまざまな部分が利用可能になるため)。

それがあなたがしていることである限り、あなたの使用法は問題ありません。避けたいのは、バックグラウンドスレッドから長い操作を渡すことによって、直接または間接的に、メインスレッドで長い操作を実行することです。

もちろん、したくない場合は、そのようにする必要はありません。代わりに使用できますpostExecute()。または、結果をどこかに保存してから、任意の種類のメッセージパッシングAPIを使用して、結果の準備ができたことをメインスレッドに通知することもできます。

于 2012-09-07T11:13:17.967 に答える