2016-04-01 2 views
0

は:onDestroy()mGDT.cancel(true)を呼び出すAsyncTask内で複数のAsyncTaskを呼び出し、必要に応じて外部タスクを停止するのは安全ですか?私はこのようなものでした場合

public class MyFragment extends Fragment 
{ 
    private GetDataTask mGDT; 

    //onCreate() and onCreateView() are implied here 

    public void runTasks() 
    { 
     new TaskOne().execute(); 
     new TaskTwo().execute(); 
     new TaskThree().execute(); 
    } 

    public class GetDataTask extends AsyncTask<Void, Void, Void> 
    { 
     @Override 
     protected Void doInBackground(Void... params) 
     { 
      runTasks(); 
     } 
    } 

    @Override 
    public void onResume() 
    { 
     super.onResume(); 
     mGDT = new GetDataTask(); 
     mGDT.execute(); 
    } 

    @Override 
    public void onDestroy() 
    { 
     super.onDestroy(); 
     mGDT.cancel(true); 
    } 
} 

でしょうがrunTasks()で実行している個々のAsyncTasksを終了しますか?このようなことを達成する最良の方法は何ですか?私は、Webからデータを収集する複数のボットを持っています。それぞれのスレッドを自分のスレッドに入れたいので、フラグメントやアクティビティが破棄された場合は、それらをすべてキャンセルする必要があります。私はAndroidプログラミングとマルチスレッドに慣れていないので、このタイプのマルチスレッドを実行する最良の方法に慣れていません。

答えて

1

これは複雑です。 cancel()は、実行中のスレッド(doInBackgroundImpl()を実行するスレッド)を中断します。外部タスクのdoInBackgroundImpl()がまだ実行されていない場合は、実行されません。それが実行または実行中の途中ですでにだ場合は、明示的

@Override 
    protected Void doInBackground(Void... params) 
    { 
     if (!Thread.isInterrupted()) { 
      runTasks(); 
     } 
    } 

そしてもちろん、中断されたフラグを探していない限り、スレッドのコードの実行がすでに条件付き中断し、チェックに合格した場合は、実行するために起こっていますそれはrunTasks()と呼ぶ予定です。

runTasks()がexecute()を実行した場合、外部タスクをキャンセルしても内部タスクは実行されません。それらが実行されると、それらはAsyncTaskのexecutorキューに置かれ、前のタスクが完了すると(またはキューが空の場合はすぐに)実行されます。

Takeaways、

1)実行される各タスクは独立しています。サブスレッドなどの概念はありません。各タスクを明示的にキャンセルする必要があります。あるタスクが別のタスクによって開始されるという事実は、cancel()のセマンティクスには関係しません。

2)スレッドを冷たくすることはできません。なぜなら、Thread.stop()はJava 1.2などから廃止されたからです。あなたが行うことができるのは中断されたことをマークすることです。そして、あなたがスレッドで使用するコードがisInterrupted()を尊重するか、それを尊重する独自のコードを書いてください。あなたの目標は、親タスクがキャンセルされたとき、あなたはただ、私はあなたが言っているのか理解しておくことを

@Override 
public void cancel(boolean interrupt) { 
    super.cancel(interrupt); 
    task1.cancel(interrupt); 
    task2.cancel(interrupt); 
    ... 
} 
+0

、のような何かを行うことができますすべてのサブタスクをキャンセルする場合、あなたの場合は

、それは安全ですonDestroy()で 'cancel(true)'を呼び出すと、個々のスレッドは終了しますか?また、2番目の段落を詳しく説明するか、少なくともexecuteOnExecutorについて説明する良いリンクを教えてください。 –

+0

'mGDT'がサブタスク(1,2,3)を起動したかどうかによって異なります。タスクを開始するmGDTのコードが実行されていない場合、mGDTをキャンセルすると、サブタスクがキャンセルされます(最初に実行されないように)。 mGDTがすでにサブタスクを開始している場合、mGDTをキャンセルしてもそれらはキャンセルされません。サブタスクでキャンセルを呼び出すために外部タスクでcancel()をオーバーライドしないでください。 –

+0

re: 'executeOnExecutor()'。最良のことは 'Executor'のAPIドキュメントを読んで' AsyncTask'のソースコードを見て、それがどのように使われているのか見てみることです。 –

関連する問題