관리 메뉴

드럼치는 프로그래머

[안드로이드] 안드로이드의 스레드(Thread) - C. 루퍼(Looper) 본문

★─Programing/☆─Android

[안드로이드] 안드로이드의 스레드(Thread) - C. 루퍼(Looper)

드럼치는한동이 2011. 11. 3. 16:38

C.  루퍼(Looper)

 

앞서 스레드에 대한 설명을 보면 핸들러를 이용하여

서로 메시지를 주고 받을수 있게 하여 서로의 변화를 알릴 수 있습니다.

 

하지만 이렇게만 알고 있다면 큰 오산입니다.

서브 스레드의 경우 메시지를 보낼 수 있는 것은 핸들러의 예제를 통해 확인했습니다.

하지만 서브 스레드의 경우 메시지를 받지는 못합니다.

메인 스레드만이 메시지를 받을 수 있습니다. 왜냐하면 메인 스레드에는 루퍼가 있기 때문입니다.

 

메시지 큐(Message Queue)

 

메시지는 스레드 간의 신호입니다. 이는 메서드처럼 호출한다고 바로 실행되는 것이 아니라 순서대로 처리가 됩니다. 자료구조에서 배우는 큐를 사용한다고 보시면 됩니다. 메시지를 쌓아 두는 공간이 바로 메시지 큐입니다.

 

루퍼(Looper)

 

루퍼메시지 큐에서 메시지를 꺼내어 핸들러로 전달하는 작업을 수행합니다.

앞서 말했듯이 메인 스레드의 경우 기본적으로 루퍼를 가집니다.

하지만 일반 작업을 수행하는 스레드의 경우 기본적으로 루퍼를 가지지 않습니다.

만약 이런 스레드가 메시지를 받아야 할 경우 루퍼를 직접 생성시켜야 합니다.

 

루퍼의 생성과 확인

 

루퍼를 직접 생성하기 위해서는 다음의 메서드를 호출합니다.

 

static void prepare()

현재 스레드를 위한 루퍼를 준비합니다.

 

static void loop()

큐에서 메시지를 꺼내 핸들러로 전달하는 루프를 실행합니다.

 

void quit()

루프를 종료시킵니다.

 

루퍼가 많아지면 혼란스러워 질 수 있지요.

또한 루퍼가 늘어난다면 코드상으로 루퍼를 식별하여 메시지를 관리해야 하기도 합니다.

그래서 어느 루퍼가 어느 스레드와 연결되어 있는지 알기 위해서는 아래의 메서드들을 사용합니다.

 

Thread getThread()

루퍼와 연결된 스레드를 구합니다.

 

static Looper getMainLooper()

주 스레드의 루퍼를 구합니다.

 

static Looper myLooper()

현재 스레드의 루퍼를 구한다. 루퍼가 없을 경우 null이 리턴됩니다.

 

루퍼 사용 예제

 

public class LooperTest extends Activity {

                  int mMainValue = 0;

                  TextView mMainText;

                  TextView mBackText;

                  EditText mNumEdit;

                  CalcThread mThread;

 

                  public void onCreate(Bundle savedInstanceState) {

                                   super.onCreate(savedInstanceState);

                                   setContentView(R.layout.thread_loopertest);

 

                                   mMainText = (TextView)findViewById(R.id.mainvalue);

                                   mBackText = (TextView)findViewById(R.id.backvalue);

                                   mNumEdit = (EditText)findViewById(R.id.number);

 

                                   Button btn = (Button)findViewById(R.id.increase);

                                   btn.setOnClickListener(new Button.OnClickListener() {

                                                     public void onClick(View v) {

                                                                       mMainValue++;

                                                                       mMainText.setText("MainValue : " + mMainValue);

                                                     }

                                   });                              

 

                                   btn = (Button)findViewById(R.id.square);

                                   btn.setOnClickListener(new Button.OnClickListener() {

                                                     public void onClick(View v) {

                                                                       Message msg = Message.obtain();

                                                                       msg.what = 0;

                                                                      msg.arg1 = Integer.parseInt(mNumEdit.getText().toString());

                                                                       mThread.mBackHandler.sendMessage(msg);

                                                     }

                                   });             

                                  

                                   btn = (Button)findViewById(R.id.root);

                                   btn.setOnClickListener(new Button.OnClickListener() {

                                                     public void onClick(View v) {

                                                                       Message msg = Message.obtain();

                                                                       msg.what = 1;

                                                                      msg.arg1 = Integer.parseInt(mNumEdit.getText().toString());

                                                                       mThread.mBackHandler.sendMessage(msg);

                                                     }

                                   });             

                                   mThread = new CalcThread(mHandler);

                                   mThread.setDaemon(true);

                                   mThread.start();

                  }

 

                  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;

 

                  CalcThread(Handler handler) {

                                   mMainHandler = handler;

                  }

//루퍼의 생성

                  public void run() {

                                   Looper.prepare();

                                   Looper.loop();

                  }

 

                  public Handler mBackHandler = new Handler() {

                                   public void handleMessage(Message msg) {

                                                     Message retmsg = Message.obtain();

                                                     switch (msg.what) {

                                                     case 0:

                                                                       try { Thread.sleep(100); } catch (InterruptedException e) {;}

                                                                       retmsg.what = 0;

                                                                       retmsg.arg1 = msg.arg1 * msg.arg1;

                                                                       break;

                                                     case 1:

                                                                       try { Thread.sleep(100); } catch (InterruptedException e) {;}

                                                                       retmsg.what = 1;

                                                                       retmsg.obj = new Double(Math.sqrt((double)msg.arg1));

                                                                       break;

                                                     }

                                       mMainHandler.sendMessage(retmsg);

                                   }

                  };

}

 

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: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:text="Square" />


  <Button android:id="@+id/root"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Root" />


  </LinearLayout>


Comments