AsyncTaskの非同期処理を制御(終了をコールバック)してくれるCountDownLatchクラスについてメモ

AsyncTaskの複数実行する場合に、全ての非同期処理がすべて終了したら何らかの処理を行う場合、
インターフェイス(リスナー)で自力で行うことも可能であるが、タスクの制御をしてくれるCountDownLatchを使うと簡単に実装できる。
CountDownLatchは指定した非同期処理数を実行する非同期処理でカウントを減算して、指定数を消化したかどうかを判定することができるハンドリング用のクラスとなる。

実装方法

例として、複数のAsyncTask(今回はTestTaskとする)を実行し、実行中にプログレスバーを表示、
すべて完了時にプログレスバーを終了するサンプルコードを示す

	private class ControlTask extends AsyncTask<Void, Void, Boolean>{

		// テストタスクのカウント数を引数に指定 ※テストで3つ実施
		CountDownLatch _latch = new CountDownLatch(3);
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			// プログレス表示処理
		}
		
		@Override
		protected Boolean doInBackground(Void... params) {
			
			try {
			    // テストタスク実行 ※3つ
				new TestTask().execute();
				new TestTask().execute();
			    new TestTask().execute();

				_latch.await(10,TimeUnit.SECONDS);
				
				return true;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return false;
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			super.onPostExecute(result);
			// プログレス終了処理
		}
		
	}
	
	private class TestTask extends AsyncTask<Void, Void, Boolean>{

		CountDownLatch _latch;
		
		public TestTask(CountDownLatch latch){
			_latch = latch;
		}
		
		@Override
		protected Boolean doInBackground(Void... params) {
			
			// なんらかのバックグラウンド処理
			return true;
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			super.onPostExecute(result);
			
			if(result){
				if(_latch != null)
					_latch.countDown();
			}
		}
		
	}

ControlTaskのCountDownLatchインスタンス生成時のコンストラクタの指定で非同期処理の実行数を指定

CountDownLatch _latch = new CountDownLatch(3);

ControlTaskのdoInBackgroundでTestTask非同期処理を上記で指定した数分実行させる。
このときにCountDownLatchのインスタンス変数を引数で渡す。※オブジェクトなので参照渡しとなる(厳密には語弊があるけど。)
各非同期処理ないではonPostExecuteで終了時にCountDownLatchのcountDownメソッドでカウントを減算させる。

_latch.countDown();

countDownの減算で、コンストラクタで指定した実行数を網羅したときに
CountDownLatchのawaitメソッドで完了し次に進むという流れになる

_latch.await(10,TimeUnit.SECONDS);

※このときawait()でも良いが上記指定の場合、完了しなくても最大10秒で次の処理に進む。念のため入れたほうが安心。

その他おすすめの備忘録

Tagged with:
 

コメントを残す