android是单线程的,在子线程中是不能修改UI线程的任何操作,所以要用一种方式让子线程中的信息返回到主线程中再做修改。这就要让主线程与子线程通信。

那如何让它们之间进行通信呢?我们用Handler这个类。Handler操作的是Message。在主线程中,消息队列是在程序启动时就自动生成的,而子线程要自己手动建立消息队列 ,Looper是用来管理消息队列的。

那么什么才是关键呢?首先,要明白Handler都是在主线程中的,也就是说,Handler类就都在主线程中运行,通俗的说就是“绑定”在主线程中。第二,Handler的触发是通过SendMessage()这个方法驱动的,注意,sendMessage 和 handleMessage这一对,一个负责发一个负责收。是哪个Handler发出的,就由哪个Handler去接收。这样msg 就不会混乱了。第三,开启一个线程唯一的方式就是执行start()方法。而只执行run()方法的,线程还是运行在主线程中。如图:

而我们要的是这样的,如图:

要让主线程与子线程通信,则用Handler 操作Message.如图:

好了看下代码吧,分享下:

MainActivity:

package com.bivin;

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.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

private Handler mMainHandler, mChildHandler;
 private TextView tv;
 private Button b;

@Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  tv = (TextView) findViewById(R.id.tv);
  b = (Button) findViewById(R.id.btn);
  Log.i("tag",Thread.currentThread().getName());
  mMainHandler = new Handler() {
   @Override
   public void handleMessage(Message msg) {
    Log.i("tag",Thread.currentThread().getName());
    //Log.i("TAG", "Got an incoming message from the child thread - "
     // + (String) msg.obj);
    tv.setText((String) msg.obj);
    super.handleMessage(msg);
   }

};

new ChildThread().start();

b.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {
    if (mChildHandler != null) {
     Log.i("tag",Thread.currentThread().getName());
     Message childmsg = mChildHandler.obtainMessage();
     childmsg.obj = mMainHandler.getLooper().getThread()
       .getName()
       + " hello!,This is mainactivity";
     
     mChildHandler.sendMessage(childmsg);
     Log.i("TAG", "Send a message to the child thread - "
       + (String) childmsg.obj);
    }
   }
   
  });
 }

@Override
 protected void onDestroy() {
  Log.i("TAG", "Stop looping the child thread's message queue");
  mChildHandler.getLooper().quit();
  super.onDestroy();
 }

private class ChildThread extends Thread {

@Override
  public void run() {
   this.setName("childthread");
   Looper.prepare();
   mChildHandler = new Handler() {

@Override
    public void handleMessage(Message msg) {
     Log.i("TAG",
       "Got an incoming message from the main thread - "
         + (String) msg.obj);
     try {
      sleep(10000);
      Message toMain = mMainHandler.obtainMessage();
      toMain.obj = "this is"
        + this.getLooper().getThread().getName()
        + ". do you send me" + (String) msg.obj + "?";
      mMainHandler.sendMessage(toMain);
      Log.i("TAG", "Send a message to the main thread - "
        + (String) toMain.obj);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     super.handleMessage(msg);
    }

};
   Log.i("TAG", "Child handler is bound to - "
     + mChildHandler.getLooper().getThread().getName());
   Looper.loop();
  }
 }

}

andriod提供了 Handler 和 Looper

* 来满足线程间的通信。例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的。

* 在Android

* ,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个是android的新概念。我们的主线程

* (UI线程)就是一个消息循环的线程

* 。针对这种消息循环的机制,我们引入一个新的机制Handler,我们有消息循环,就要往消息循环里面发送相应的消息,自定义消息一般都会有自己对应的处理

* ,消息的发送和清除,把这些都封装在Handler里面,注意Handler只是针对那

* 些有Looper的线程,不管是UI线程还是子线程,只要你有Looper,我就可以往你的消息队列里面添加东西,并做相应的处理。

* 但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。

*

* 一个Handler的创建它就会被绑定到这个线程的消息队列中,如果是在主线程创建的,那就不需要写代码来创建消息队列了,默认的消息队列会在主线程被创建。

* 但是如果是在子线程的话,就必须在创建Handler之前先初始化线程的消息队列。

多线程,主线程与子线程的通信Handler Message sendmessage与handlemessage obtainmessage相关推荐

  1. 多线程——主线程和子线程退出关系

    分清两个概念 主线程和当前进程的关系:当前进程由主线程和若干个子线程组成. 若当前进程退出后,子线程也会跟着一起退出:若只是主线程退出,仍要分两种情况分析:实际上主线程退出后子线程的状态依赖于它所在的 ...

  2. Android之用Handler实现主线程和子线程互相通信以及子线程和子线程之间的通信

    1.上代码 activity_main.xml文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/ ...

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

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

  4. c++主线程等待子线程结束_简单明了的 Python 多线程来了 | 原力计划

    作者 | 万里羊责编 | 王晓曼出品 | CSDN博客线程和进程计算机的核心是CPU,它承担了所有的计算任务,就像是一座工厂在时刻运行.如果工厂的资源有限,一次只能供一个车间来使用,也就是说当一个车间 ...

  5. 【多线程】学习记录七种主线程等待子线程结束之后在执行的方法

    最近遇到一个问题需要主线程等待所有的子线程结束,才能开始执行,统计所有的子线程执行结果,返回,网上翻阅各种资料,最后记录一下,找到七种方案 第一种:while循环 对于"等待所有的子线程结束 ...

  6. java主线程控制子线程_CountDownLatch控制主线程等子线程执行完--Java多线程

    1.[代码]CountDownLatch控制主线程等子线程执行完--Java多线程 package com.sihuatech.common; import java.util.concurrent. ...

  7. 主线程和子线程的区别,线程之间的通信

    1.主线程来向子线程发送消息的方法 在平时写程序时,我们一般都是在子线程中向主线程发送消息,从而完成请求的处理,这个很常见,不用多说了.那么有时候,我们也可能碰到这样子的一种需求:需要主线程来向子线程 ...

  8. Java多线程之----主线程会等待子线程结束再结束么,怎么让主线程等待子线程结束呐?

    首先给出结论: 主线程和子线程之间没有谁先谁后结束这种关联,它们只是各自负责自己的线程任务,如果该线程的任务结束了,该线程自然会结束运行. talk is cheap,show me the code ...

  9. java中子线程与主线程通信_Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息...

    之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码: ...

最新文章

  1. 菜鸟也来学习ORACLE(1)_linux下安装oracle 11g
  2. 硬核!我的导师手写129页毕业论文,堪比打印!
  3. 如何在Java中将String转换为int?
  4. SpringMVC入门案例
  5. 算法与数据结构(part3)--数据结构概述
  6. cstring判断包含字符串_Python字符串方法之-解决判断问题
  7. nssl1298-网站计划【线段树】
  8. gcovr 安装_Kudu 1.8.0 编译安装配置
  9. 如何识别哭泣csdn_如何让敏感的孩子,不再那么敏感?不是溺爱,而是懂得这些方法...
  10. 题目:求100以内的全部素数,每行输出10个。1不是素数
  11. 计算机专业英语词汇1695词(35天记忆)
  12. java电商ERP源码 跨境电商ERP源码 ERP源码
  13. Android函数插桩,Android 代码插桩 ~ Misaki’s Blog
  14. python中计算ln和lg的方法
  15. velodyne+cartographer 2D构建栅格地图
  16. 容量 Byte、KB、MB、GB、TB、PB、EB、ZB、YB、NB、DB、CB、XB
  17. VOT, OTB——目标追踪的发展概况
  18. AOSP中make clean与make clobber的区别
  19. [JIRA] 从3.6.2旧版升级到新版6.0.8的详细过程
  20. html下拉式日历,C#实现日历样式的下拉式计算器

热门文章

  1. linux安装Wine版微信(正常显示中文,可以发送文件)
  2. 微软sql服务器可以禁用,禁用索引和约束 - SQL Server | Microsoft Docs
  3. ActionContext介绍
  4. 基于PythonGUI的图形学系统绘图软件
  5. 本行卡修改密码基本流程说明
  6. 大话数据结构与算法(一)
  7. 小程序上线之企业工商注册
  8. 利用Java实现端口扫描器
  9. 用openGL实现用黑白相间的棋盘图案填充多边形
  10. 阿里云接口实现短信发送java版