5-1 自定义与线程相关的Handler

1.在线程中通过Looper.prepare()方法创建一个与线程相关的Looper对象;
2. 在线程中通过Handler的new关键字,创建一个Handler对象,这个对象在创建的时候会关联上1中创建的Looper对象
3. 调用Looper对象的loop()方法去轮询它的MessageQueue
4. 通过其他的线程拿到这个线程的Handler对象之后调用sendMessage()之后,在这个线程中就可以进行Message的处理了。

我们一般是在主线程中创建Handler对象,在主线程中处理Message,在子线程中调用这个Handler对象的sendMessage()来发送message。所以Handler是在哪个线程创建就有哪个线程处理Message和轮询,而由别的线程负责给这个Handler发送Message。

1.注意:在主线程中创建的Handler的handleMessage()方法不要写耗时的操作,否则会导致UI卡死,因为这个handleMessage()方法是在UI线程中调用的。

package com.example.yzx;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.TextView;public class SecondActivity extends Activity {private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {System.out.println("UI---------" + Thread.currentThread());};};class MyThread extends Thread {public Handler handler;@Overridepublic void run() {// TODO Auto-generated method stub
            Looper.prepare();handler = new Handler() {@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubSystem.out.println("currentThead:" + Thread.currentThread());}};Looper.loop();}}private MyThread thread;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);TextView textView = new TextView(this);textView.setText("hellow Handler");setContentView(textView);thread = new MyThread();thread.start();try {Thread.sleep(500);} catch (InterruptedException e) {// TODO Auto-generated catch block
            e.printStackTrace();}thread.handler.sendEmptyMessage(1);handler.sendEmptyMessage(1);}
}

5-2 HanlderThread是什么 (11:51)

HandlerThread避免多线程导致空指针问题。
handlerthread 默认【创建一个looper然后和一handler关联,那么所有的handleMessage方法是在一个子线程中进行,可以用handlerthread模拟一个异步任务,将主线程的任务发送个子线程,处理一些比较耗时操作

-----------------------------------------------------------------------------------------

1.一个Handler的创建它就会被绑定到这个线程的消息队列中,如果是在主线程创建的,那就不需要写代码来创建消息队列了,默认的消息队列会在主线程被创建。但是如果是在子线程的话,就必须在创建Handler之前先初始化线程的消息队列

2.HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它有个Looper成员变量。这个Looper其实就是对消息队列以及队列处理逻辑的封装,简单说就是 消息队列+消息循环。

在其run()方法中,调用Looper.myLooper()获得一个looper对象。
  synchronized (this) {
    mLooper = Looper.myLooper();
    notifyAll();
在创建handler时使用getLooper()方法,其实现其实是一直等待looper对象的获得。
  while (isAlive() && mLooper == null) {
    try {
      wait();
      }
   }

3.Handler在创建的时候可以指定Looper,这样通过Handler的sendMessage()方法发送出去的消息就会添加到指定Looper里面的MessageQueue里面去。在不指定Looper的情况下,Handler绑定的是创建它的线程的Looper。如果这个线程的Looper不存在,程序将抛出"Can't create handler inside thread that has not called Looper.prepare()"。

  1. 创建Handler的时指定的looper,可以是别的线程创建的。所以Handler中MessageQueue的轮询不一定非要是创建Handler的线程进行,还可以在别的线程中进行。
    这个时候我们就需要使用HandlerThread这个类来创建这个Looper了,这样消息的处理就在新创建的HandlerThread中进行。(如图)
    mThread = new HandlerThread("Handler Thread");
    mHandler = new Handler(mThread.getLooper()){
    public void handleMessage(android.os.Message msg) {
    ... };
    };

  两个线程切换的过程中,looper没有创建 会抛出控制异常
  handlerThread用来避免这个异常

package com.example.yzx;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.widget.TextView;public class threeActivity extends Activity {private TextView text;private HandlerThread thread;private Handler handler;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);text = new TextView(this);text.setText("handler Thread");setContentView(text);thread = new HandlerThread("handler thread");thread.start();handler = new Handler(thread.getLooper()) {@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubSystem.out.println("current thread---------->" + Thread.currentThread());}};handler.sendEmptyMessage(1);}}

转载于:https://www.cnblogs.com/crazyzx/articles/5477398.html

5 Handler与子线程相关推荐

  1. handler回调主线程_Android使用Handler实现子线程与子线程、子线程与主线程之间通信...

    转载:https://blog.csdn.net/shaoenxiao/article/details/54561753 今天这篇文章只讲一下怎么使用Handler实现子线程与子线程之间.子线程与主线 ...

  2. Android攻城狮 Handler与子线程

    Handler和线程是相关联的.再次强调:不可以在主线程中做耗时操作,就比如示例里面主线程中的 handlerMessage(),不能执行耗时操作.创建一个与自定义线程相关的Handler的代码: c ...

  3. Handler更新子线程数据

    listView = view.findViewById(R.id.listview);//解析网络数据new Thread() {@Overridepublic void run() {super. ...

  4. android Handler Message传递参数,handler子线程和主线程通讯

    创建Handler private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) { ...

  5. Android之HandlerThread源码分析和简单使用(主线程和子线程通信、子线程和子线程通信)

    1.先熟悉handler方式实现主线程和子线程互相通信方式,子线程和子线程的通信方式 如果不熟悉或者忘记了,请参考我的这篇博客     Android之用Handler实现主线程和子线程互相通信以及子 ...

  6. Handler消息机制(四):子线程可以创建Handler吗

    默认情况下,ActivityThread类为我们创建的了主线程的Looper和消息队列,所以当你创建Handler之后发送消息的时候,消息的轮训和handle都是在ui线程进行的.这种情况属于子线程给 ...

  7. Looper、Handler应用---实现主线程向子线程发送消息

    准备知识: Looper类:为一个线程开启一个消息循环,里面有一个消息队列,新线程是没有开启消息循环的,所以需要用到Looper的方法创建消息循环(主线程除外,主线程会自动为其创建Looper对象,开 ...

  8. Android中Handler消息传递机制应用之子线程不允许操作主线程的组件

    场景 进程 一个Android应用就是一个一个进程,每个应用在各自的进程中运行. 线程 比进程更小的独立运行的基本单位,一个进程可以包含多个线程. 要求 一个TextView和一个Button,点击B ...

  9. 19 Handler 子线程向主线程发送信息

    案例一 Message创建三种方法: package com.example.day19_handler_demo1;import android.os.Bundle; import android. ...

最新文章

  1. KindEditor自动过滤首行缩进和全角空格的解决方法
  2. bashrc与profile的相关知识
  3. 实施工程师常用linux命令,009Linux管理日常使用的基本命令
  4. 定时任务的实现原理,看完就能手撸一个!
  5. 字符串匹配之KMP算法详解
  6. 机械师开机黑屏自动修复此计算机,机械师F117-V-BISO还原教程
  7. 贝叶斯推理(Bayes Reasoning)、独立与因式分解
  8. 二极管(一):反向恢复时间
  9. 微信小程序:最新微信登录授权并获取openid等信息
  10. 【解决方案】GB28181/RTSP/Onvif/HikSDK/Ehome协议视频共享平台EasyCVR人脸识别助力打造智慧安检
  11. 医院信息化建设(2)---医疗业务
  12. 中国社科中外合作办学双证博士创新与领导力管理学博士
  13. HTML中设置td的字体颜色
  14. 赋值运算和赋值表达式
  15. 什么认证在云计算行业内的含金量最大?考试费用贵不贵?
  16. Android隐藏软键盘
  17. Batch Normalization + Internal Covariate Shift(论文理解)
  18. java中floa后面有L吗_java中float和double输出结果到底是多少位
  19. 看片显示服务器不稳定,无限“看片”,资源随便下,这回爽了!
  20. 怀旧服美服哪个服务器人最多,暴雪:魔兽世界经典怀旧服美服排队人数恐破万...

热门文章

  1. 租网站服务器安全吗,租用的服务器安全吗
  2. Spring Cloud:connect time out
  3. linux WiFi源码解析,Wifi移植浅析
  4. 连接MySQL数据库时报 Public Key Retrieval is not allowed 异常
  5. putty 远程linux桌面,Linux远程桌面工具Xming+Putty的搭建
  6. 美国伊利诺伊大学香槟分校计算机专业,伊利诺伊大学香槟分校计算机科学排名第7(2020年TFE美国排名)...
  7. 解决linux系统CentOS下调整home和根分区大小的方法
  8. mongodb 安装启动
  9. 华为宣布:免费培养2万名Python开发者!
  10. 12 款 Linux 终端推荐