Android编程的Looper和Handler和HandlerThread
小标 2018-05-23 来源 : 阅读 1431 评论 0

摘要:在Android编程中,Handler相信大家并不陌生,我们在主线程new一个这样的Handler,然后在异步操作的时候,我们需要刷新UI,这个时候,我们通常会用到handler.post()或者handler.sendMessage()。希望对大家学习Android编程有所帮助。

在Android编程中,Handler相信大家并不陌生,我们在主线程new一个这样的Handler,然后在异步操作的时候,我们需要刷新UI,这个时候,我们通常会用到handler.post()或者handler.sendMessage()。希望对大家学习Android编程有所帮助。

那么,对于Looper和HandlerThread比较陌生的同学,先看一下下面的实例吧。

我们在oncreate方法中new一个子线程,然后再子线程new一个handler,并执行handler.sendEmptyMessage。大家看看有什么问题。

 

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.msgtest);
        new Thread() {
            @Override
            public void run() {
                Handler handler = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        Log.e("xx", Thread.currentThread().getName() + " 11111");
                    }
                };
                handler.sendEmptyMessage(1);
            }
        }.start();
    }

   

 

没错,报错了


java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
                                                       at android.os.Handler.<init>(Handler.java:200)
                                                       at android.os.Handler.<init>(Handler.java:114)
                                                       at com.kv.mymeet.MsgTestAct$1$1.<init>(MsgTestAct.java:0)
                                                       at com.kv.mymeet.MsgTestAct$1.run(MsgTestAct.java:50)</init></init></init>

   

 

在子线程,如果直接执行Handler的操作,会报错。系统提示需要有Looper。即正确的写法是


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.msgtest);
    new Thread() {
        @Override
        public void run() {
            Looper.prepare();
            Handler handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    Log.e("xx", Thread.currentThread().getName() + " 11111");
                }
            };
            handler.sendEmptyMessage(1);
            Looper.loop();
        }
    }.start();
}

   

1. Looper类用来为一个线程开启一个消息循环。
默认情况下android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。)
Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。

2.通常是通过Handler对象来与Looper进行交互的。Handler可看做是Looper的一个接口,用来向指定的Looper发送消息及定义处理方法。
默认情况下Handler会与其被定义时所在线程的Looper绑定,比如,Handler在主线程中定义,那么它是与主线程的Looper绑定。
mainHandler = new Handler() 等价于new Handler(Looper.myLooper())。

3.Looper.myLooper():获取当前进程的looper对象,类似的 Looper.getMainLooper() 用于获取主线程的Looper对象。


4.Looper.loop(); 让Looper开始工作,从消息队列里取消息,处理消息。
注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。


5. 基于以上知识,可实现主线程给子线程(非主线程)发送消息。

那么,再来说说HandlerThread的用法。

HandlerThread其实就是已经实现了消息循环的线程。

上面的代码,如果用HandlerThread写,也可以这样写。


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.msgtest);
     
    HandlerThread handlerThread = new HandlerThread("handler handler");
    handlerThread.start();
    final Handler handler = new Handler(handlerThread.getLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.e("xx", Thread.currentThread().getName() + " 11111");
        }
    };
    new Thread() {
        @Override
        public void run() {
            Looper.prepare();
 
            handler.sendEmptyMessage(1);
            Looper.loop();
        }
    }.start();
}

   

本文由职坐标整理并发布,了解更多内容,请关注职坐标移动开发Android频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved