android 백그라운드 처리 작업 ( handler, AsyncTask )

시간이 걸리는 작업을 처리하는 경우 알림 대화상자를 띄워서 사용자에게 알려주고 백그라운드에서 작업을 처리하는 방법에 대해서 알아봅니다.


<< handler 를 이용한 방법 >>

핸들러형 변수를 하나 만들고 작업을 쓰레드를 생성하는 메서드(startWriteTwitter())의 쓰레드 내에서 호출합니다.

이렇게 하면 기존에 UI 쓰레드에서 돌던 트위터 보내기 메서드가 새로 생성한 서브 쓰레드에서 돌기 때문에

UI 쓰레드가 먼추는 현상이 생기지 않게 됩니다. 그리고 그와 동시에 알림 다이알로그 박스도 보여줄 수 있게 됩니다.

그리고 작업이 끝나면 핸들러에 메세지를 보내 진행중 대화 상자를 없애주는 작업을 합니다.

주의점은 쓰레드 내에서 동작하는 작업은 UI 처리를 하는 작업이 없어야 합니다.


  // 클래스 변수
  private ProgressDialog mLoagindDialog; // Loading Dialog
  

  // 트위터에 보내기를 처리하기 위한 핸들러
  private Handler mHandler = new Handler()
  {
    public void handleMessage(Message msg)
    {
      if (msg.what == 100) // 보내기 완료
      {
        mLoagindDialog.dismiss();
        Toast.makeText(TwitterCon3.this, "트위터에 보내기 성공", Toast.LENGTH_LONG).show();
      }
      else if (msg.what == -100) // 보내기 실패 
      {
        mLoagindDialog.dismiss(); // 다이얼로그 삭제
        Toast.makeText(TwitterCon3.this, "트위터에 보내기 실패", Toast.LENGTH_LONG).show();
      }
      else
      {
        mLoagindDialog.dismiss(); // 다이얼로그 삭제
      }
    }
  };

  // 트위터에 보내기 시작
  private void startWriteTwitter()
  {
    mLoagindDialog = ProgressDialog.show(this, null, "트위터로 보내는 중입니다...", true, false);
    Thread thread = new Thread(new Runnable()
    {
      public void run()
      {
        write();	// 실제 처리할 작업
      }
    });
    thread.start();
  }

private void write()
  {
	...
	if(rv == 1){  // 전송 성공
		mHandler.sendEmptyMessage(100); // 핸들러를 호출하여 다이얼로그 상자를 없애줍니다.
	}else{ // 전송 실패
		mHandler.sendEmptyMessage(-100); // 핸들러를 호출하여 다이얼로그 상자를 없애줍니다.
	}
  }


<< AsyncTask를 이용한 방법 >>


어싱크 태스크는 new DoPostTwitter().execute(); 이런식으로 호출하게 되면

execute() 메서드의 호출에 의해 콜백 메서드인 

protected Long doInBackground(String... params) 이 호출되게 됩니다. 

물론 그 전에 protected void onPreExecute() 이 먼저 호출이 되지요 

간단하게 과정을 간략화 하면 


1) new DoPostTwitter().execute();  호출

2) protected void onPreExecute() 호출 : 진행중 다이얼로그 박스 보여줌

3) protected Long doInBackground(String... params) 호출 : 실제 작업 처리

4) 3)의 작업이 끝나면 protected void onPostExecute(Long result) 호출 : 작업 후 처리 (다이얼로그 박스 삭제)


  // 클래스 변수
  private ProgressDialog mLoagindDialog; // Loading Dialog  
  private Context mContext;

// 트위터에 보내기 시작
  private void startWriteTwitter()
  {
    new DoPostTwitter().execute();
  }

//AsyncTask로 트위터 보내기 처리 
 private class DoPostTwitter extends AsyncTask<String, Integer, Long> 
 {
   @Override
   protected void onPreExecute()  // 진행중 다이얼로그 박스 보여줌
   {
     super.onPreExecute();
     mLoagindDialog = ProgressDialog.show(mContext, null, "트위터로 보내는 중입니다...", true, false);
   }
   
   @Override
   protected Long doInBackground(String... params)	 // 백그라운드 실제 작업 처리
   {
     int result = write();
     return Long.valueOf(result);
   }

   @Override
   protected void onPostExecute(Long result)  // 작업후 처리
   {
     super.onPostExecute(result);
     mLoagindDialog.dismiss();		// 다이얼로그 박스 삭제
     
     int rslt = result.intValue();
     
     if (rslt == 1)
       Toast.makeText(mContext, "트위터에 보내기 성공", Toast.LENGTH_LONG).show();
     else
       Toast.makeText(mContext, "트위터에 보내기 실패", Toast.LENGTH_LONG).show();
   }
 }

<< Handler 를 이용한 시계 표시 : android 현재시간 실시간 출력 예 >>

private Timer mTimer;
private TextView tv_event_time2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_time);
		tv_event_time2 = (TextView) findViewById(R.id.tv_event_time2);
		setStartTime();
		
	}
	private void setStartTime(){
		MainTimerTask timerTask = new MainTimerTask();
		mTimer = new Timer();
		mTimer.schedule(timerTask, 500, 1000);
	}
	private Handler mHandler = new Handler();
	private Runnable mUpdateTimeTask = new Runnable() {
		public void run() {
			String myTime = "";
			Calendar cal = Calendar.getInstance();
			myTime = String.format(Locale.KOREAN,"%02d : %02d : %02d",
			            cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
			tv_event_time2.setText(myTime);
		}	
	};
	
	class MainTimerTask extends TimerTask {
		public void run() {	
			mHandler.post(mUpdateTimeTask);
		}
	}
	@Override
	protected void onDestroy() {
		mTimer.cancel();
		super.onDestroy();
	}
	@Override
	protected void onPause() {
		mTimer.cancel();
		super.onPause();
	}

<< Handler 를 이용한 실행예, 호출부

    private final static int GET_JSON = 0;
    private final static int DO_STH = 1;
    ...
                new Thread(){
                    public void run(){
                        JSONdata1 = readJSON();
                        messageHandler.sendEmptyMessage(GET_JSON);
                    }
                }.start();

<< Handler 를 이용한 실행예, 실행부

private Handler messageHandler= new Handler(){

        public void handleMessage(Message msg){
            super.handleMessage(msg);

            int what = msg.what;

            switch(what) {
                case GET_JSON:
                    if (textview == null)
                        textview = (TextView) findViewById(R.id.textView);

                    textview.setText(JSONdata1);
                    progressDialog.dismiss();
                    break;

                case DO_STH:
                    break;
            }
        }
    };


<< 참고한 자료 >>

http://jeehun.egloos.com/category/Android



+ Recent posts