스레드를 반드시 써야 하는 이유는 잠시 살펴봤고 이번에는 실제 스레드를 사용해 보자.
스레드 테스트를 하고자 간단하게 소스를 작성한다. 아래는 소스이다.
package kr.corej.myapplication;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 간단하게 Thread 생성자만으로 스레드 실행
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
firstWork(getApplicationContext());
}
}).start();
SelectThread thread = new SelectThread();
thread.setDaemon(true);
thread.start();
}
public static void firstWork(Context context) {
// 일단 작업하고 보자.
}
class SelectThread extends Thread {
public void run() {
Message msg = handler.obtainMessage();
// 데이터 조회하는 작업
msg.arg1 = dataSelection();
handler.sendMessage(msg);
}
}
private void countdown() {
for (int j = 0; j < 10; j++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
int dataSelection() {
// UI Thread: progress linear
runOnUiThread(new Runnable() {
@Override
public void run() {
// 데이터 처리 중임을 알리는 로딩바를 보여주는 작업
}
});
// 데이터 조회 시간이 10초 정도 걸린다고 치고.
countdown();
// ListView 같은 곳에 담을 데이터를 불러와서 담고, 정렬하는 작업
// 데이터를 불러들일 때 시간이 걸릴 수 있기 때문에 스레드로 처리
// 조회된 데이터가 10건이라고 가정, 10건을 return
return 10;
}
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
// 스레드 작업이 끝나면 실제 레이아웃을 건드리는 작업은 여기서 처리한다. (조회된 건수로 변경하는 작업 포함)
// 시간이 오래 걸리는 작업이 끝났기 때문에 로딩바도 없애주는 작업
Toast.makeText(getApplicationContext(), msg.arg1 + "건이 조회되었습니다.",
Toast.LENGTH_SHORT).show();
return true;
}
});
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
// noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
조금씩 떼어서 좀 더 상세히 보자.
// 간단하게 Thread 생성자만으로 스레드 실행
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
firstWork(getApplicationContext());
}
}).start();
onCreate 메소드 안에 스레드 생성자이다.
이렇게 간단하게 스레드를 생성해서 사용할 수도 있다. 스레드 뭐 별거 없다.
firstWork 함수 부분에 스레드로 돌릴 작업 내용을 넣으면 된다.
이처럼 간단한 스레드는 작업이 끝난 후에 레이아웃을 변경하거나 당장 화면에 영향을 미치는 작업이 아닐 때 쓸 수 있다.
SelectThread thread = new SelectThread();
thread.setDaemon(true);
thread.start();
이 부분은 Thread를 상속해서 만든 SelectThread 객체 생성과 호출 부분이다.
setDaemon(true) 메소드는 데몬 스레드로 메인 스레드가 종료되면 함께 종료된다.
// UI Thread: progress linear
runOnUiThread(new Runnable() {
@Override
public void run() {
// 데이터 처리 중임을 알리는 로딩바를 보여주는 작업
}
});
dataSelection() 함수 안에 있는 runOnUiThread 역시 스레드인데 UI 변화에 관련된 처리를 담당한다.
(메인 스레드가 아닌) 스레드 실행 중에는 안드로이드 UI를 변경이나 조작할 수 없다.
저 부분은 데이터 처리 중임을 알리는 로딩바를 Visible 시키거나 UI를 조작하는 작업을 한다는 가정인데 언급한 것처럼 dataSelection 함수 자체가 스레드 실행 중에 있으므로 메인 스레드 도움 없이 UI를 변경하면 안 된다.
끝으로 SelectThread 작업이 끝나면 핸들러를 호출해서 마무리한다.
handler.sendMessage(msg);
핸들러 부분은 핸들러 안 주석으로 상세설명을 대신한다.
'안드로이드' 카테고리의 다른 글
안드로이드 스튜디오(Android Studio)에서 Eclipse Code Formatter Plugin 추가와 Google Style 적용해보자. (4) | 2016.02.15 |
---|---|
안드로이드 스레드(Thread) AsyncTask를 써보자. (6) | 2015.02.02 |
안드로이드 스튜디오(Android Studio) 유용한 단축키를 정리해놓자. (0) | 2015.01.31 |
안드로이드 스튜디오(Android Studio) 설치와 글꼴(font)을 설정해보자. (0) | 2015.01.31 |
안드로이드 스레드(Thread)는 왜 써야 하는가. (2) | 2015.01.30 |