루퍼(looper)
지금까지 쓰레드끼리 Message객체를 만들어서 정보를 주고 받는다고 생각하면 잘못된 것입니다. 예제들을 보면 메인쓰레드만 Message객체를 받고 있음을 알 수 있습니다.
즉 메인쓰레드는 루퍼란 것을 가지고 있기때문에 메시지를 받을 수 있었습니다.
루퍼란놈은 메시지큐에서 메시지를 꺼내서 핸들러에 보내는 역할을 합니다(이전 소스보면 메인쓰레드 안에 Handler mHanler = new Handler()를 했음을 알 수 있습니다.
그렇다면 서브쓰레드에도 메시지를 받을 수 있게 할려면?
서브쓰레드에도 루퍼를 만들어주면 됩니다.
static void prepare() : 현재 쓰레드를 위한 루퍼를 준비합니다
static void loop() 큐에서 메시지를 꺼내 핸들러로 전달하는 루프를 실행합니다(일종의 start임)
void quit() 루프를 종료합니다.(루퍼를 없앤다는 얘기)
다음은 루퍼를 구하는 메소드입니다.
Thread getThread() 루퍼와 연결된 쓰레드를 구합니다.
static Looper getMainLooper() 메인쓰레드의 루퍼를 구합니다.
static Looper myLooper() 현재쓰레드의 루퍼를 구합니다. 없으면 null반환
주석 열심히 달아놨습니다. 읽어봐서 이해안되시면 댓글달아주세요. 제가 이해 못한거니까요.
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/mainvalue"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="MainValue : 0"
/>
<Button
android:id="@+id/increase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="Increase"
/>
<EditText
android:id="@+id/number"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numeric="integer"
android:text="5"
/>
<TextView
android:id="@+id/backvalue"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="BackValue : 0"
/>
<Button
android:id="@+id/square"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="Square"
/>
<Button
android:id="@+id/root"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="Root"
/>
</LinearLayout>
자바파일
package com.android.ex93;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
public class ex93 extends Activity {
int mMainValue = 0;
TextView mMainText;
TextView mBackText;
EditText mNumEdit;
CalcThread mThread;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMainText = (TextView)findViewById(R.id.mainvalue);
mBackText = (TextView)findViewById(R.id.backvalue);
mNumEdit = (EditText)findViewById(R.id.number);
mThread = new CalcThread(mHandler);
mThread.setDaemon(true);//데몬쓰레드로 설정
mThread.start();//시작
}
public void mOnClick(View v) {
Message msg;
//각 버튼 눌렀을때 처리부분 이정도는 직관적으로 이해가 되리라 믿습니다.
switch (v.getId()) {
case R.id.increase:
mMainValue++;
mMainText.setText("MainValue : " + mMainValue);
break;
case R.id.square:
msg = new Message();//메시지를 만들고 메시지에 정보 넣기
msg.what = 0;
msg.arg1 = Integer.parseInt(mNumEdit.getText().toString());
mThread.mBackHandler.sendMessage(msg);//서브쓰레드에 메시지 보내기
break;
case R.id.root:
msg = new Message();//메시지를 만들고 메시지에 정보 넣기
msg.what = 1;
msg.arg1 = Integer.parseInt(mNumEdit.getText().toString());
mThread.mBackHandler.sendMessage(msg);
break;
}
}
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
mBackText.setText("Square Result : " + msg.arg1);
break;
case 1:
mBackText.setText("Root Result : " + ((Double)msg.obj).doubleValue());
break;
}
}
};
}
class CalcThread extends Thread {
Handler mMainHandler;
Handler mBackHandler;
CalcThread(Handler handler) {
mMainHandler = handler;
}
public void run() {
Looper.prepare();//루퍼만들기~
mBackHandler = new Handler() {//메인쓰레드가 보낸 메시지를 여기서 받음
//물론 받기 이전에 루퍼를 만들어줘야됨
public void handleMessage(Message msg) {
Message retmsg = new Message();
switch (msg.what) {
case 0:
try {
Thread.sleep(200);//이건 그냥 시간차 주고 싶어서 써본거
}catch (InterruptedException e) {;}
retmsg.what = 0;
retmsg.arg1 = msg.arg1 * msg.arg1;//받은 메시지를 처리하는 부분
break;
case 1:
try {
Thread.sleep(200); //이건 그냥 시간차 주고 싶어서 써본거
} catch (InterruptedException e) {;}
retmsg.what = 1;
retmsg.obj = new Double(Math.sqrt((double)msg.arg1));//받은 메시지를 처리하는 부분
break;
}
//받은 메시지를 잘 가공한뒤에 다시 메인쓰레드한테 보냄
//여기서는 메시지 큐까지 보내게됨
mMainHandler.sendMessage(retmsg);
}
};
//메시지큐에 있는 내용을 실제 핸들러한테 보냄!
//서브쓰레드 -> 메시지큐-> 메인쓰레드 핸들러 이렇게 감
Looper.loop();
}
}
'프로그래밍 > 안드로이드' 카테고리의 다른 글
안드로이드 쓰레드 진행상황 프로그래스바로 보여주기 (0) | 2012.08.22 |
---|---|
안드로이드 쓰레드로 ANR(Application not response)방지법 (0) | 2012.08.22 |
안드로이드 작업스케쥴링 두번째 postDelayed 메소드를 써보자. (0) | 2012.08.22 |
안드로이드 작업스케쥴링 sendMessageDelayed를 언제 쓰지 (0) | 2012.08.22 |
안드로이드 쓰레드 4번째 메시지 풀을 이용하는 방법(obtain 메소드) (0) | 2012.08.21 |
안드로이드 쓰레드 3번째 쓰레드를 구현하는 클래스와 메인 클래스를 따로 만들어서 처리해보자 (0) | 2012.08.21 |
안드로이드 쓰레드 구현 2번째 방법 post 메소드를 이용하자. (0) | 2012.08.21 |
안드로이드 쓰레드 첫번째 예제 handleMessage 구현하는 방법 (1) | 2012.08.21 |