Android

AsyncTask 작업을 동기화하기(wait / notify 사용)

tomato13 2012. 8. 4. 17:28

비동기화를 위해 제공되는 AsyncTask이지만 AsyncTask 들 간에는 동기화할 경우가 있을 것이다. 예를 드면 AsyncTask1이 수행되기 이전에 AsyncTask2는 수행되지 않아야 한다는등.

이 때에는 java object의 wait/notify함수를 사용할 수 있다. 단, 주의해야할 사항으로 wait / notify는 같은 object간에만 효력이 있다는 것이다. (아래 예제 코드 참조)

또한 wait / notify할때에는 해당 함수를 synchronized 로 설정해야함을 주의해야한다. 그렇지 않으면 수행시에 에러가 발생한다. 


public class AsyncTaskDemo2 extends Activity implements View.OnClickListener

{


ProgressBar progressBar;

TextView textResult;

Button btnExecuteTask;

private static boolean mAsyncTaskExecute = false;


/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);


progressBar = (ProgressBar) findViewById(R.id.progressBar);

textResult = (TextView) findViewById(R.id.textResult);

btnExecuteTask = (Button) findViewById(R.id.btnExecuteTask);


btnExecuteTask.setOnClickListener(this);

}


public void onClick(View v)

{

try

{

WaitNotify waitNotify = new WaitNotify();

DoComplecatedJob asyncTask1 = new DoComplecatedJob(waitNotify);

asyncTask1.execute("AsyncTask1");

DoComplecatedJob asyncTask2 = new DoComplecatedJob(waitNotify);

asyncTask2.execute("AsyncTask2");

}

catch(Exception e)

{

Log.i("Debug", e.getMessage());

}

}

private class WaitNotify{

synchronized public void mWait()

{

try

{

wait();

}

catch(Exception e)

{

Log.i("Debug", e.getMessage());

}

}

synchronized public void mNotify()

{

try

{

notify();

}

catch(Exception e)

{

Log.i("Debug", e.getMessage());

}

}

}


// AsyncTask클래스는 항상 Subclassing 해서 사용 해야 함.

// 사용 자료형은

// background 작업에 사용할 data의 자료형: String 형

// background 작업 진행 표시를 위해 사용할 인자: Integer형

// background 작업의 결과를 표현할 자료형: Long

private class DoComplecatedJob extends AsyncTask<String, Integer, Integer>

{

private String mTitle = null;

private WaitNotify mWaitNotify = null;

public DoComplecatedJob(WaitNotify aWaitNotify)

{

mWaitNotify = aWaitNotify;

}


// UI 스레드에서 AsynchTask객체.execute(...) 명령으로 실행되는 callback

@Override

protected Integer doInBackground(String... strData)

{

if(mAsyncTaskExecute)

{

mWaitNotify.mWait();

}

mAsyncTaskExecute = true;

mTitle = strData[0];

int cnt = 0;

while (true)

{

if(cnt>5)

{

break;

}

else

{

try

{

Thread.sleep(1000);

}

catch(Exception e)

{

Log.i("Debug", e.getMessage());

}

publishProgress(cnt++);

}

}

return 0;

}

@Override

protected void onProgressUpdate(Integer... progress)

{

Log.i("Debug", "[" + mTitle + "]" + ": " + progress[0]);

}

@Override

    protected void onPostExecute(Integer result) {

Log.i("Debug", onPostExecute");

mWaitNotify.mNotify();

mAsyncTaskExecute = false;

    }

}

}