Handler主要用于不同线程之间的通信,尤其是普通线程通过handler机制发送message给主线程(UI线程)来更新UI,或者是把耗时的操作发送给service让service来执行。
Handler主要处理的对象有两种:一种是message,一种是runable
Handler具体介绍请看---------------->>>>>>
Handler有四种构造函数:
1:Handler()
2:Handler(Callback callback)
3:Handler(Looper looper)
4:Handler(Looper looper, Callback callback)
Handler有两类主要的发送信息的方法:
1:boolean post(Runnable r) //发送一个Runnable对象,并执行该对象的run方法。(特别注意:这个对象是在handler的所在的线程中运行)
2:boolean sendMessage(Message msg) //发送一个message信息,让handleMessage方法来处理
如果对Looper不熟悉---------------->>>>>>
本文分别对这四种构造函数进行一个简单的总结O O。
一:Handler()
代码一:sendMessage(Message msg)实现Thread发送message到UI线程(主线程)的handler来更新UI的方法
把Message送入消息队列,handler机制自动循环取出数据用handleMessage方法来处理,可以根据Message的what属性来进行分支语句选择。
我们把Handler和Thread的方法实现都单独拿出来变成一个类,这样可以方便重用和让代码更加清晰一些O O
MainActivity.java
public class MainActivity extends Activity {
private Button startButton;
private TextView showTextView;
private Handler myhandler1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlayout);
startButton = (Button)findViewById(R.id.btn_st);
showTextView = (TextView)findViewById(R.id.tv_show);
myhandler1 = new MyHandler(MainActivity.this);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new MyThread(myhandler1).start();
}
});
}
public void updareTheUI(){
//do some updating operate
showTextView.setText("success!!");
}
}
public class MyHandler extends Handler {
private MainActivity mainActivity;
public MyHandler(MainActivity main) {
super();
mainActivity=main;
}
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
int what = msg.what;
switch (what) {
case 1:
updareTheUI();
break;
default:
break;
}
}
private void updareTheUI(){
//mainActivity.updareTheUI();
}
}
MyThread.java
public class MyThread extends Thread {
private Handler handler;
public MyThread(Handler h){
handler=h;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
//run方法
Message message = Message.obtain();
message.what=1;
handler.sendMessage(message);
//run方法
}
}
代码二:post(runable r)实现用handler来重复运行一个runable对象
(Ps.如果费时的操作或者网络,数据库操作是不行的,因为本质上还是运行在同一个线程中,调用的是run方法而不是start方法)
简单的把所有代码写在同一类中,方便内部类调用外部类的实例
public class MainActivity extends Activity {
private Button startButton;
private TextView showTextView;
private Handler myhandler1;
private Button stop;
Runnable runnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlayout);
showTextView = (TextView)findViewById(R.id.tv_show);
myhandler1=new Handler();
runnable = new Runnable()
{
public void run()
{
showTextView.append(" Go ");
//延时1s后又将线程加入到线程队列中
myhandler1.postDelayed(runnable, 1000);
//或者先sleep(1000);然后myhandler1.post(runnable); 一样的效果
}
};
myhandler1.post(runnable);
//手动停止按钮
stop = (Button)findViewById(R.id.btn_stop);
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
myhandler1.removeCallbacks(runnable);
}
});
}
}
二:Handler(Callback callback)----------实现handMessage方法的重用
Callback时Handler类内部的一个接口:
public interface Callback {
public boolean handleMessage(Message msg);
}
他仅仅要求实现一个handleMessage的方法。
代码三:
class myCallback implements Handler.Callback{
@Override
public boolean handleMessage(Message arg0) {
// TODO Auto-generated method stub
//do something
if(arg0.what==1)
return true;
else
return false;
}
}
public class MainActivity extends Activity {
private Handler myhandler1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlayout);
myhandler1=new Handler(new myCallback());
new Thread(){
public void run() {
myhandler1.sendMessage(Message.obtain(myhandler1,1));
};
}.start();
}
}
个人简单的理解:其实这个方法和直接继承Handler并重写handleMessage方法没什么太大的不同O O
无非是,你的handleMessage方法可以重用到别处,或是如何。。。
或者说,根据Handler源代码中的dispathMessage方法,这个机制的作用就是一层一层的传递这个消息,这个消息能被哪一层的消息处理函数handleMessage来处理。
比如,你创建了一个Handler,然后别人需要扩展你的handler的时候,可以直接调用这种构造方法来实现他的特别的处理机制。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
三:Handler(Looper looper)
不知道你是否有所疑问,为什么主线程可以接受并处理message的消息,并不断的循环提取message。或是是否所有的线程都可以创建一个Handler对象。
1:普通线程变成Looper线程
普通需要在run方法中添加两个函数才能变成一个Looper线程:只有绑定了对应的Looper才可以使用Handler对象,并处理消息。
代码三:
class myThread extends Thread {
public Handler mHandler;
public void run() {
//先准备,准备会new一个messageQueue来存放消息
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
//loop()相当于开启了message收取的循环
Looper.loop();
}
}
这样子一个普通线程就成为了一个Looper线程,线程内可以直接创建Handler来处理消息。2:主线程(UI线程)
一个程序的主线程是怎么来的呢?
程序运行时,AcitivityManager会产生一个新的进程,这个新进程会先创建一个ActivityThread实例,在ActivityThread实例中就会创建并绑定对应的Looper,
之后才启动我们看到的Activity界面。
使用:
这个构造函数一般结合Looper.getMainLooper()来使用,Looper.getMainLooper()用于获取主线成的Looper,
所以,new Handler(Looper.getMainLooper())就可以得到一个关联主线程的Handler实例。
自己随便想出来的一个奇怪的Handler(Looper looper)的实例:主线程发送信息给其他线程,让其他线程来处理费时信息。。
代码四:
class MyThread extends Thread{
private Looper myLooper;
private Handler h;
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (myLooper) {
Looper.prepare();
myLooper = Looper.myLooper();
}
Looper.loop();
}
public Looper getLooper() {
return myLooper;
}
}
public class MainActivity extends Activity {
private Button startButton;
private TextView showTextView;
private Handler myhandler1;
private Button stop;
private int x=0;
Runnable runnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlayout);
showTextView = (TextView)findViewById(R.id.tv_show);
MyThread thread = new MyThread();
thread.start();
Looper looper=null;
while(looper==null){
looper = thread.getLooper();
}
Log.i("MyLooper", looper.toString());
Log.i("main", Looper.getMainLooper().toString());
myhandler1 = new Handler(looper){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.i(Thread.currentThread().getName(),Thread.currentThread().getName()+"-"+"haha"+x);
//我们可以在这个新线程中做一些费时的计算或者处理一类的操作。。
//因为整个Handler其实是MainActivity的内部类,所以可以方便的直接调用MainActivity内的实例。
}
};
for(int i = 0 ;i<100;i++)
{
Log.i(Thread.currentThread().getName(),Thread.currentThread().getName());
myhandler1.sendMessage(Message.obtain());
}
}
}
四:Handler(Looper looper, Callback callback)
第四中构造函数相当与2和3的结合。其实根据上面的例子我们可以发现Handler函数最重要的实例就是Looper实例,最重要的处理消息的方法就是handleMessage方法,这个构造函数相当于是直接在构造的时候就把整个Handler定义好了,不用在去找他的对应线程或是重写handleMessage方法。
总结:Handler的主要功能就是,发送消息和处理消息
主要用来实现异步回调功能,在新线程中做完一个费时的操作后,启动这个回调函数。
更简单的说就是