浅谈Android中的Handler

Android中的Handler, Looper, MessageQueue和Thread的相互关系

面试常问的一个问题,也是Android里面非常重要、非常基础的一个问题。这篇blog就来简单总结下这个知识点。


Handler类说明 

Handler类用来发送和处理消息(Message)以及和线程的消息队列(MessageQueue)关联的Runnable对象。

Handler是属于主线程的一个工具类。

当你创建一个新的Handler对象,它会和创建它的这个线程/线程的消息队列绑定,从那个时刻开始,它将向这个消息队列传递消息和runnable对象,并且当它们从队列中出来时执行它们。

Handler主要有两种用途:

  1.合理调度安排消息和runnable对象,使它们在将来的某个点被执行。

  2.将一个动作入队安排在非当前线程执行。

使用Handler我通常使用sendMessage()和HandlerMessage()两方法。sendMessage方法允许你入队一个消息对象(Message),包含一个bundle数据,之后将会被Handler的handleMessage(Message)方法所处理。

Handler,Looper和MessageQueue就是简单的三角关系。Looper和MessageQueue一一对应,创建一个Looper的同时,会创建一个MessageQueue。而Handler与它们的关系,只是简单的聚集关系,即Handler里会引用当前线程里的特定Looper和MessageQueue。

Handler传递runnable的例子

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView textView;
    private Button startBtn;
    private Button endBtn;

    //使用handler首先要创建一个handler
    private Handler mHandler=new Handler();

    //要用handler来处理多线程可以使用实现Runnable接口,这里先定义该接口
    //线程中运行该接口的run函数
    Runnable updateRunnable=new Runnable() {
        @Override
        public void run() {
            //线程每次执行时输出"UpdateThread..."文字,且自动换行
            textView.append("\nUpdateThread...");
            //延时1s后又将线程加入到线程队列中
            mHandler.postDelayed(updateRunnable,1000);
        }
    };

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

        textView= (TextView) findViewById(R.id.tv_handler);
        startBtn= (Button) findViewById(R.id.btn_start);
        endBtn= (Button) findViewById(R.id.btn_end);

        startBtn.setOnClickListener(this);
        endBtn.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {

        switch (v.getId())
        {
            case R.id.btn_start:
                //将线程接口立即加入线程队列中
                mHandler.post(updateRunnable);
                break;
            case R.id.btn_end:
                //将接口从线程队列中移除
                mHandler.removeCallbacks(updateRunnable);
                break;
        }
    }
}

Handler通过handleMessage()和sendMessage()方法来实现进度条展示的例子

public class ProgressHandlerAct extends AppCompatActivity{

    private ProgressBar progressBar;
    private Button startBtn;

    //创建handler,并且执行
    private Handler mHandler=new Handler(){

        @Override
        public void handleMessage(Message msg) {
            //显示进度条
            progressBar.setProgress(msg.arg1);
            //将线程加入到handler的线程队列中
            mHandler.post(updateThread);
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_progress_handler);

        progressBar= (ProgressBar) findViewById(R.id.pb);
        startBtn= (Button) findViewById(R.id.btn_start);

        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //设置progressBar可见
                progressBar.setVisibility(View.VISIBLE);
                //通过上面定义的handler将线程加入handler中
                mHandler.post(updateThread);
            }
        });
    }

    //handler中添加的runnable线程
    Runnable updateThread=new Runnable() {

        int i=0;

        @Override
        public void run() {

            i+=10;
            //获取上面handler中的message
            Message msg=mHandler.obtainMessage();
            //将进度条显示的值赋值给消息的arg1参数
            msg.arg1=i;

            //延时1s
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //关键点1,将消息通过handler发送到消息队列中
            mHandler.sendMessage(msg);

            if(i==100){
                mHandler.removeCallbacks(updateThread);
            }
        }
    };
}

上面2个例子表面上看handler使用了post方法启动了runnbale,其实启动的线程和activity主线程是同一个线程,因为它只是 运行了线程的run方法,而不是start方法。

今天就简单总结到这里,有时间会继续进行完善。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值