올해는 머신러닝이다.
[팁]handler 와 looper 의 이해 본문
Android – Thread Messaging
Android provides Handler and Looper for threads to communication with each other.
For example, a child thread is launched to create an image from the web. After it is done, it notifies the main thread (or the UI thread) by sending a message using the handler that’s bound to the main thread’s message queue.
The data produced by the child thread can also be included in the message. I often use this pattern if I want the main thread to update the UI with the data produced by the child thread (you probably already know why if you have been playing with threads in Android).
When a Handler is created, it’s bound to the message queue of the thread that created it.
If you create it in the main thread, you don’t need any extra code to loop the message queue for the main thread since it’s already been started when you run your application. However, if you are creating a Handler in a child thread, you need to initialize the thread to listen to its message queue before creating the Handler.
Whenever the Handler receives a message, it would run the handleMessage(…). You can do some expensive operations in there. For example, you need to constantly send some data to the server. It probably would be more efficient if you have a thread listening for the messages to do the job instead of creating and running a new thread each time you need to do so.
If you are done with the looper, don’t forget to stop it by using its quit() method. For example:
mChildHandler.getLooper().quit();
Here is an example of creating a two-way communication between the main thread and a child thread:
example)
public class ThreadMessaging extends Activity {
private static final String TAG = "ThreadMessaging";
private TextView mTextView;
private Handler mMainHandler, mChildHandler;
private Handler mh;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView = (TextView)findViewById(R.id.text);
/*
* Start the child thread.
*/
new ChildThread().start();
/*
* Create the main handler on the main thread so it is bound to the main
* thread's message queue.
*/
mMainHandler = new Handler() {
public void handleMessage(Message msg) {
Log.i(TAG, "Got an incoming message from the child thread - " + (String)msg.obj);
/*
* Handle the message coming from the child thread.
*/
mTextView.setText(mTextView.getText() + (String)msg.obj + "\n");
}
};
Log.i(TAG, "Main handler is bound to - " + mMainHandler.getLooper().getThread().getName());
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
/*
* Send a message to the child thread.
*/
Message msg = mChildHandler.obtainMessage();
msg.obj = mMainHandler.getLooper().getThread().getName() + " says Hello";
mChildHandler.sendMessage(msg);
Log.i(TAG, "Send a message to the child thread - " + (String)msg.obj);
}
});
}
@Override
protected void onDestroy() {
Log.i(TAG, "Stop looping the child thread's message queue");
/*
* Remember to stop the looper
*/
mChildHandler.getLooper().quit();
super.onDestroy();
}
class ChildThread extends Thread {
private static final String INNER_TAG = "ChildThread";
public void run() {
this.setName("child");
/*
* You have to prepare the looper before creating the handler.
*/
Looper.prepare();
/*
* Create the child handler on the child thread so it is bound to the
* child thread's message queue.
*/
mChildHandler = new Handler() {
public void handleMessage(Message msg) {
Log.i(INNER_TAG, "Got an incoming message from the main thread - " + (String)msg.obj);
/*
* Do some expensive operation there. For example, you need
* to constantly send some data to the server.
*/
try {
/*
* Mocking an expensive operation. It takes 100 ms to
* complete.
*/
sleep(100);
/*
* Send the processing result back to the main thread.
*/
Message toMain = mMainHandler.obtainMessage();
toMain.obj = "This is " + this.getLooper().getThread().getName() +
". Did you send me \"" + (String)msg.obj + "\"?";
mMainHandler.sendMessage(toMain);
Log.i(INNER_TAG, "Send a message to the main thread - " + (String)toMain.obj);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Log.i(INNER_TAG, "Child handler is bound to - " + mChildHandler.getLooper().getThread().getName());
/*
* Start looping the message queue of this thread.
*/
Looper.loop();
}
}
}
'Android > Tip&Tech' 카테고리의 다른 글
[출처]안드로이드 태스크,어피니티,플래그 (0) | 2011.12.07 |
---|---|
[펌]리플렉션(Reflection)을 활용한 안드로이드 위젯 매핑(Mapping) 간소화 하기 (0) | 2011.12.07 |
[팁]AutoCompleteTextView랑 DB랑 싱크시키기 (3) | 2011.12.05 |
[팁]ActionBar 커스텀하기 (0) | 2011.12.01 |
[팁]HorizontalScrollView랑 scrollview 같이 사용하기 (0) | 2011.11.30 |