アプリケーションの汎用タスク マネージャー クラスとして機能することを目的とした、AsyncTask を拡張するクラスがあります。
問題:進行状況ダイアログが表示されるが、決して閉じられないという奇妙な動作が発生します。
ここに置かれた場合、任意の Log.d("","") ステートメントが起動するため、onPostExecute() がすべてのタスク インスタンスに対して呼び出されると確信しています。トースト メッセージもこのメソッド内から表示されますが、できません。静的ダイアログを閉じます。
AsyncTask(s) が UI スレッドにアクセスできるのは [onPreExecute() と onPostExecute()] の 2 か所だけであることを理解しているので、runOnUiThread() でダイアログを閉じようとする必要はないと思います。
executeTask() へのすべての呼び出しは、さまざまなアクティビティのさまざまな onCreate() メソッドから行われ、UI 要素の一部を設定する前にネットワーク経由でデータを取得する必要があり、常に現在のアクティビティのコンテキストをタスクに渡します。
関連するタスクが完了するまでアクティビティを切り替えないので、アクティビティ コンテキスト オブジェクトはまだ有効であると思います (これを仮定するのは間違っていますか??) デバッグ中にそれらのいずれかが null であることを発見したことはありません。
これはタイミングの問題でしょうか?また、ほとんどの場合、アクティビティが表示される前にすべてのタスクが完了していることを DDMS が示していることも確認しました。onCreate() で使用
new Handler().postDelayed(runnable_which_calls_these_tasks,10);
し、foo_X() に遅延コードを追加すると、アクティビティは遅延なく表示されますが、ダイアログはdismiss() しません。
この問題に関するかなりの数の記事を読みましたが、どこが間違っているのか正確にはわかりません. すべてのアクティビティ クラスのように各タスクを定義したくありません。private inner class Task1 extends AsyncTask<>
また、(これが唯一の解決策でない限り) このディスカッションで述べたように、すべてのアクティビティ参照をアプリケーション オブジェクトにロードしたくありません。私は何かが足りないのですか?.
私はこれに1週間費やしましたが、まったく無知です:(誰かが私を導き、何が欠けているかを教えてくれれば素晴らしいことです.
クラス定義は次のとおりです:[明確にするために、無関係なアプリケーション固有のコードをいくつか削除しました]
public class NetworkTask extends AsyncTask<Void, Integer, Boolean> {
private Context UIcontext;
private int operationType;
private static ProgressDialog dialog;
private static int taskCount;
private NetworkTask(int operationType Context context){
this.UIcontext = context;
this.operationType = operationType;
if (taskCount++ == 0)
dialog = ProgressDialog.show(context,"","Loading...");
}
public static Boolean executeTask(int operationType, Context context) {
return new NetworkTask(operationType, context).execute().get();
}
@Override
protected void onPreExecute(){
super.onPreExecute();
if (taskCount == 1)
dialog.show();
}
@Override
protected Boolean doInBackground(Void... arg0) {
switch(operationType){
case TYPE_1:
foo1();
break;
case TYPE_2:
foo2();
break;
case TYPE_3:
foo3();
break;
case TYPE_4:
foo4();
break;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
taskCount--;
if (dialog.isShowing() && taskCount == 0){
dialog.dismiss();
}else {
Toast.makeText(UIcontext, "Task#"+ operationType+", m done, but there are "+taskCount+" more", 5).show();
}
}
}