最近学习了下Handler,以前在android里面传值用的都是broadcast的,从来没用过handler。因为初学的时候看了Mars的教学视频,Mars说的我一头雾水,决定放弃。
不知道Handler的请先看以下博文
Android 之 Handler总结
http://blog.csdn.net/t12x3456/article/details/7706155
主线程中有多个handler的情况
http://www.cnblogs.com/transmuse/archive/2011/05/16/2048073.html
不再赘述。
Message,MessageQueue,Looper,Handler分别是什么请看
http://gundumw100.iteye.com/blog/858233
总之
- 该线程有Looper才能用Handler
- message由发送该message的Handler处理
- Handler机制类似于中断
Handler典型应用是子线程发送数据到主线程,在主线程中更新UI。
但是当主线程需要向子线程发送数据时,可以在子线程建立Handler。
以下代码演示了主线程和子线程分别建立Handler对传消息。
需要注意几点
- 本例中子线程和主线程的Handler分别传入了不同的Callback触发不同动作
- 子线程默认没有Looper需要调用Looper.prepare();才能使用Handler
- Looper.loop();使子线程开启消息循环才能接收,子线程默认没有开启,开启后线程将不会自动结束
- Looper.myLooper().quit();退出消息循环,线程结束
Activity 代码
package com.example.testhandler;
import com.example.test1.R;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Looper;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
/**
* 测试子线thread 里的 handler looper
* @author he_xingpeng
*
*/
public class Main2Activity extends Activity {
private static final int ONE = 1;
public static final int TWO = 2;
private static String TAG = "Main2Activity" ;
private Button button;
private Handler mainHandler;
private SubThread subThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainHandler = new Handler(new MainCallback());
button = (Button) findViewById(R.id.button1);
Object o;
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
startThread();
}
});
}
private void startThread(){
showPID();
subThread = new SubThread() ;
subThread.start();
}
private static void showPID(){
Log.d(TAG,"PID=>startThread()=>"+Thread.currentThread().getId());
}
class SubThread extends Thread{
public Handler subHandler;
@Override
public void run() {
// TODO Auto-generated method stub
Looper.prepare(); //子线程默认没有loopoer,需要开启
subHandler = new Handler(new SubCallback());
Message msg = mainHandler.obtainMessage(ONE);
mainHandler.sendMessage(msg);
showPID();
Looper.loop(); //子线程进入loop状态等待message来到
}
}
class MainCallback implements Callback{
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
switch(msg.what){
case ONE: //由主线程处理
showPID();
button.setText("" + ONE);
Log.d(TAG,"ONE");
if(subThread.isAlive()){
subThread.subHandler.obtainMessage(TWO).sendToTarget();
}
break;
}
return true;
}
}
class SubCallback implements Callback{
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
switch(msg.what){
case TWO: //由子线程处理
showPID();
Log.d(TAG,"TWO");
Looper.myLooper().quit(); //子线程Looper退出,线程结束
break;
}
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;
}
}
XML布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Button" />
</RelativeLayout>