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的例子。

posted @ 2015-11-27 17:37  一日学一日功  阅读(1761)  评论(0)    收藏  举报