Handler를 이용해서 특정 시간 후에 특정 작업을 실행시키기


특정 시간 후에 특정한 작업이 실행되도록 하는 방법으로 AlarmManager를 이용할수 있지만 간단하게 처리할수 있는 방법으로는 Handler를 이용하면 더 쉽게 처리할수가 있다.

대표적으로 ProgressDialog를 특정 시간 경과 후 종료 시키는 방법을 구현한다면 아래와 같이 간단히 처리할수 있다.

아래 코드는 7초 후에 ProgressDialog를 중지시키는 코드이다.

실행하기 원하는 작업(코드)를 Runnable 인터페이스의 추상 메소드인 public void run() 안에 두면 run안의 코드가 특정 시간 경과후(여기서는 7초) 실행이 된다.

즉 ProgressDialog의 객체인 pDialog를 show() 한 후에 


      ProgressDialog pDialog = new ProgressDialog(this, 

                                                              AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);

      pDialog.setCancelable(false);

      pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);

      pDialog.setMessage("주변의 BLE 장치를 검색 중입니다.");

      pDialog.show();


      mHandler.postDelayed(new Runnable() {

          @Override

          public void run() {

              pDialog.dismiss();

          }

      }, 7000);



Handler 클래스의 해당 메소드를 보면 다음과 같이 되어 있다.


public final boolean postDelayed (Runnable r, long delayMillis)

⇒ Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses. The runnable will be run on the thread to which this handler is attached.


r : The Runnable that will be executed.

delayMillis : The delay (in milliseconds) until the Runnable will be executed.


Runnable 객체를 message queue에 추가한 후에 delayMillis 시간 경과 후에 Runnalbe 객체 r을 실행시킨다. 이렇게 처리하면 Thread로는 처리 불가능한 UI 관련 작업도 처리할수 있다.


r : 실행할 코드를 담고 있는 Runnable 객체. Runnable의 추상 메소드 public void run()안에 있는 코드를 실행한다.

delayMillis : 여기에 설정된 시간만큼 경과 후에 r을 실행한다.





callback 메소드가 있는 클래스의 객체 선언 법


abstract 클래스도 아니고 interface도 아닌 

일반 클래스임에도 콜백 메소드(시스템에 의해 자동 호출되는 메소드)가 있을 경우 abstract 클래스나 interface와 유사한 방식으로 객체를 생성을 할 수 있다. 

아래 두 경우를 보면 모두 일반 클래스이다.


public class Handler extends Object

public class PhoneStateListener extends Object


그런데 이들 클래스 안에 콜백 메서드를 사용하기 위해 다음과 같이 mHandler라는 객체를 다음과 같이 생성한다.


 Handler mHandler = new Handler(){ 

     @Override

     public void handleMessage(Message msg){ //이게 콜백 메소드

         //여기서 원하는 기능 수행

     }

  };


위의 handleMessage() 메소드는 핸들러로 메시가 들어올때 즉 이 핸들러 호출이 있을 때 시스템에 의해 이 메소드 호출된다.



PhoneStateListener mPhoneState = new PhoneStateListener(){

    public void onCallStateChanged(int state, String incomingNumber){ //이게 콜백 메소드이다.

    switch(state){

    case TelephonyManager.CALL_STATE_IDLE :

    txt.append("\n☆ 전화 상태 : 대기 상태");

    break;

    case TelephonyManager.CALL_STATE_OFFHOOK :

    txt.append("\n☆ 전화 상태 : 통화 중");

    break;

    case TelephonyManager.CALL_STATE_RINGING :

    txt.append("\n☆ 전화가 왔습니다 : " + incomingNumber);

    break;

    }

    }

    };





아래와 같은 에러를 만나면 원인은 쓰레드 안에 쓰레드를 사용하였기 때문에 

오류가 발생하였다.


java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()


해결 방법은 쓰레드 안에 Handler를 새로 선언하여 사용하면 된다.


View.OnClickListener clickSomeThing = new View.OnClickListener(){

@Override

public void onClick(View v){

Handler mHandler = new Handler(Looper.getMainLooper());

mHandler.postDelayed(new Runnable(){

@Override

public void run() {

doSomeMethod(); //쓰레드 안에서 실행되는 쓰레드

}, 0);

}

};


+ Recent posts