안드로이드 handler, AsyncThread 사용하기


Handler


안드로이드의 UI는 메인 스레드에서만 변경할 수 있습니다.

그래서 만약 서브 스레드에서 UI를 변경하고 싶으면 Handler를 사용해야합니다.

즉, 서브 스레드 -> Handler -> 메인 스레드 과정을 거쳐서 서브 스레드에서 UI를 변경할 수 있습니다.


아래 예제는 서브 스레드에서 TextView의 글자를 바꾸는 예제입니다.

Handler를 생성하는 스레드만 다른 스레드가 보내는 Message 객체나 Runnable 객체를 받을 수 있으므로 

메인 스레드에서 Handler를 생성해 줘야합니다.

public class MainActivity extends AppCompatActivity {
TextView tv;
int i;

Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg) {
tv.setText("숫자 : "+ i);

}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

tv = (TextView)findViewById(R.id.text1);
}

public void onClick(View v){
SubThread th = new SubThread();
th.start();
}

class SubThread extends Thread{
@Override
public void run() {
for(i = 1; i <= 10; i++){
try {
Thread.sleep(1000);
Message msg = mhandler.obtainMessage();
mhandler.sendMessage(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}


Handler를 이용해서 로딩화면을 구현해 줄 수 있습니다.

Handler의 postDelayed는 첫 번째 인자로 Runnable 객체, 두 번째 인자로 입력된 시간 후에 Runnable객체가 실행되게 합니다.

아래 예제에서는 3초후에 화면이 바뀌도록 설정한 예제입니다.

public class LoadingActivity extends AppCompatActivity {
Handler mhandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loading);
mhandler = new Handler();
mhandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent i = new Intent(LoadingActivity.this, MainActivity.class);
startActivity(i);
finish();
}
}, 3000);
}
}


AsyncTask


AsyncTask는 Handler를 사용하지 않고 UI 처리를 할 수 있고, Background 작업을 할 수  있습니다.

AsyncTask에는 5개의 Override 메소드가 있습니다.

  • onPreExecute() - AsyncTask가 실행될 때 처음 실행되는 메소드로 UI 변경을 할 수 있습니다.
  • doInBackground(Params...) - 백그라운드 스레드에서 처리되는 메소드 입니다. 진행 중 UI작업이 필요한 경우 publish Progress함수를 호출하면 UI 작업을 하는 onProgressUpdate가 호출됩니다.
  • onProgressUpdate - doInBackground에서 publishProgress를 호출하면 실행되는 메소드로 UI를 변경할 수 있습니다.
  • onPostExecute(Result) - doInBackGround 메소드 종료 후 호출되고 doInBackGround의 리턴 값을 받습니다.
  • onCancelled() - doInBackground 메소드에서 작업이 호출되면 onPostExecute 대신 호출됩니다.


생성법은 아래와 같습니다.

AsyncTask<String, Integer, Long>  

  • String - doInBackground 메소드의 전달 값 
  • Integer - onProgressUpdate 메소드의 전달 값
  • Void - doInBackground의 반환 값

class myTask extends AsyncTask<String,Integer,Void>{
@Override
protected void onPreExecute() {
super.onPreExecute();
}

@Override
protected Long doInBackground(String... params) {
return null;
}

@Override
protected void onProgressUpdate(Integer... values) {
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}


@Override
protected void onCancelled() {
super.onCancelled();
}
}

생성한 AsyncTask를 실행하고 싶을 때는 .execute() 종료하고 싶을 때는 .cancel(true)를 생성합니다.

.execute에 넣어준 인자는 doInBackground에서 사용할 수 있습니다.

myTask task = new myTask();
task.execute(0);
task.cancel(true);


아래 예제는 Handler와 AsyncTask를 사용한 예제입니다.

코드는 깃 허브에서 볼 수 있습니다.

https://github.com/Ywook/AndroidPractice11


  


 


+ Recent posts