내용 보기

작성자

관리자 (IP : 172.17.0.1)

날짜

2020-07-09 08:06

제목

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


비동기화를 위해 제공되는 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;
        }
    }
}
cs



출처1

http://m.blog.daum.net/jhmoon77/17456070

출처2