Android中Handler的理解(结合线程)
主要是参考一下这两篇文章的内容,然后加上自己的理解:
http://mobile.51cto.com/aprogram-442833.htm
http://www.cnblogs.com/devinzhang/archive/2011/12/30/2306980.html
当Android应用程序启动时,会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件进行事件分发,例如:当点击一个 Button ,Android会分发事件到Button上,来响应你的操作。
如果此时需要一个耗时的操作,例如: 联网读取数据, 或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示 "强制关闭"。我遇到的一种的实际情况,就是地图数据的获取(直接放到主线程中),就会导致程序崩溃。
我们需要把这些耗时的操作,放在一个子线程中。而主线程主要负责界面的更新。
Handler就是解决子线程和主线程通信的问题;Handler是运行在主线程中的(UI线程中), 它与子线程是通过Message对象来传递数据的。
Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据) ,然后完成UI的更新的工作。
Handler的特点:
(1)安排消息或Runnable 在某个主线程中某个地方执行;
(2)安排一个动作在不同的线程中执行。
Handler分发消息的方法:
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
post类方法是排列一个Runnable对象到主线程队列中,
sendMessage类方法, 是发送Message对象到队列中,等待更新。
这里需要把整个过程理清楚:

在子线程中通过Handler向发送Message,Handler先把这些消息放到消息队列中。然后Looper通过DisopatchMessage分发消息,分发的目标就是Handler。然后Hander调用回调函数(如果设置callback的话),如果没有就调用子类的中的handleMessage来处理和更新UI
Android中每一个Thread都跟着一个Looper,Looper可以帮助Thread维护一个消息队列的。Looper不断地从MessageQueue中抽取Message执行。
looper资料请参考这篇文章
http://blog.sina.com.cn/s/blog_5da93c8f0100y4ul.html
使用Handler发送Message比较好理解,但是使用Handler发送Runnable却不太一样。
Handler把
请参考这篇文章
http://www.cnblogs.com/akira90/archive/2013/03/06/2946740.html
Runnable是一个接口,不是一个线程,一般线程会实现Runnable。所以如果使用匿名内部类实现Runnable是运行在UI主线程的,如果使用实现这个Runnable接口的线程类,则是运行在对应线程的。
Runnable 并不一定是新开一个线程,比如下面的调用方法就是运行在UI主线程中的:
Handler mHandler=new Handler();
mHandler.post(new Runnable(){
@Override public void run()
{ // TODO Auto-generated method stub
}
});
调用handler的post方法,把Runnable对象(一般是Runnable的子类)传过去;handler会在looper中调用这个Runnable的Run方法执行。
其实主要过程就是:
子线程通过Handler----->发送Msg或者Runnable到---->Message Queue消息队列;
Looper从消息队列中取出消息--------->DispatchMessage然后分发消息——--->分发的目标就是Handler------>Handler调用回调函数或者Handler的子类的handleMessage来处理消息,并且更新UI
Handler类有好几种构造函数,一种是带looper的,一种是带callback回调函数的。
public Handler(Looper L){ …………………… }
public Handler(Looper L,Callback callback){ ………………………… }
如果Handler对象使用的是带callback的Handler的构造函数,那么凡是发送到这个Handler的消息,都会被这个Callback函数处理。
如果Handler对象使用的是不带callback的Handler的构造函数,那么发送到这个Handler的消息,会被类Handler中的handleMessage()这个函数处理。
这篇文章可以好好看看:
http://blog.sina.com.cn/s/blog_5da93c8f0100y4ul.html
下边是网上的一个例子:http://mobile.51cto.com/aprogram-442833.htm
我试了一下,可以使用。
import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.Button; public class MainActivity extends Activity { private Button bt; private MyHandler myHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt=(Button)findViewById(R.id.mbt); myHandler = new MyHandler(); MyThread m = new MyThread(); new Thread(m).start(); } class MyHandler extends Handler{ public MyHandler(){ }
// public MyHandler(Looper L){ // super(L); // }
@Override public void handleMessage(Message msg){ Log.d("My Handler","handlerMessage。。。。"); super.handleMessage(msg); Bundle b = msg.getData(); String color=b.getString("color"); MainActivity.this.bt.append(color); } } class MyThread implements Runnable{ public void run(){ try{ Thread.sleep(1000); }catch(InterruptedException e){ e.printStackTrace(); } Log.d("Thread。。。。。","mThrad。。。"); Message msg=new Message(); Bundle b=new Bundle(); b.putString("color", "我的"); msg.setData(b); MainActivity.this.myHandler.sendMessage(msg); } } // class MyThread extendsThread{ // public void run(){ // try{ // Thread.sleep(10000); // }catch(InterruptedException e){ // e.printStackTrace(); // } // Log.d("Thread。。。。。","mThrad。。。"); // Message msg=new Message(); // Bundle b=new Bundle(); // b.putString("color", "我的"); // msg.setData(b); // MainActivity.this.myHandler.sendMessage(msg); // } // } }
这篇文章主要是结合线程说的,因为有线程的存在,有可能会把Handler的作用弄的不清晰。
可以看我的另一篇的。单独没有线程的Handler的例子。

浙公网安备 33010602011771号