Android之Handler

本文深入解析Android中的Handler机制,包括其工作原理、关键组件(如Looper、MessageQueue和Message)的作用,以及如何通过Handler实现子线程与主线程间的通信以更新UI。
摘要由CSDN通过智能技术生成

handler的基本使用

1.Handler是什么?

    主要是为了接受子线程的消息,配合主线程更新UI。

    在Android系统内,主线程应该专注于更新UI,而不会把精力放到,请求网络,或者本地文件上,从而阻塞自己,使得自己的应用出现anr(application not responding)的情况。

    还有就是Android中Android UI组件是线程不安全的,也就是说,更新UI的操作希望只在主线程中进行,而不希望在子线程中进行,Handler自然而然的就出现了。

2.Handler、Looper、MessageQueue 与 Message

    looper:循环读取消息,交由Handler处理,一个线程对应一个looper
    MessageQueue:消息队列,一个looper对应一个消息队列
    Message:消息,一个消息队列有多个消息
    Handler:处理与分发消息,每个消息最多指定一个handler处理

这里写图片描述

3.handler中的方法

    post系列
    post(Runnable)
    postAtTime(Runnable,long)
    postDelayed(Runnable long)

    Send系列
    sendEmptyMessage(int)
    sendMessage(Message)
    sendMessageAtTime(Message,long)
    sendMessageDelayed(Message,long)

可以看一下post(Runable r)的实现

public final boolean post(Runable r)
{
    return sendMessageDelayed(getPostMessage(r),long)
}

//而getpostMessage则是将runable包装成message
private static Message gerPostMessage(Runnable r)
{
    Message m = Message.obtain();
    m.callback = r;
    return m;
}
在处理message的时候,如果Message.callback不为空则使用这个将优先使用callba来处理
Handle.mcallback不为空则使用mcallback处理
如果前两个都不存在则使用handleMessage处理

4.handler的构造方法

4.1 handler是如何与Looper联系起来的,这个主要在构造方法里面。

4.2 先看一下handler类的成员变量

public class Handler{
    //...部分
    final MessageQueue mQueqe;
    final Looper mLooper;
    //这里就上上述的mcallback
    final CallBack mcallback;

}

4.3Handler 的构造方法

//handler有多个构造方法
public Handler();
public Handler(Callback callback);
public Handler(Looper looper);
public Handler(Callback callback,Looper looper);


//我们来看一个public Handler()
public Handler()
{
    //...部分
    mLooper = Looper.myLooper();//获取当前线程中的Looper实例
    mQueue = Looper.mQueue;
}

//对于下面的例子便是使用了这个构造函数, 并获取了UI主线程的Looper
//对于普通线程来说,我们需要自己开启线程对应的looper
class LooperThread extends Thread
{
    public Handler mHandler;
    public void run()
    {
        //主线程使用Looper.prepareMainLooper()
        Looper.prepare();
        mHandler = new Handler(){ //重写处理消息方法};
        Looper.loop();//进入消息循环
    }
}


5.基本使用

5.1MyThread子线程

package com.example.myhandler;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class MyThread extends Thread{
    private Handler myHandler;

    public MyThread(Handler h) {
        // TODO Auto-generated constructor stub
        this.myHandler = h;
    }

    @Override
    public void run() {
        super.run();
        while(true)
        {
            Message m = new Message();
            m.what = 0x1010;
            Bundle data = new Bundle();
            data.putString("mes", "我是新消息");
            m.setData(data);
            try {
                //睡眠一秒钟
                Thread.sleep(1000);
                //再发送消息
                myHandler.sendMessage(m);
                Log.i("sss", "122212");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

}

5.2.MainActivity

package com.example.myhandler;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    TextView textview;
    Button btn;
    Handler myHandler ;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textview = (TextView)findViewById(R.id.textview);
        btn = (Button)findViewById(R.id.btn);
        myHandler = new Handler(MainActivity.this.getMainLooper())
                {
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        if(msg.what == 0x1010)
                        {
                            textview.append(msg.getData().getString("mes"));
                        }
                    }
                };

        //持有handler的引用可以向他这个线程的looper发送消息
        MyThread tt = new MyThread(myHandler);
        tt.start();

    }

    @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;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值