多线程,主线程与子线程的通信Handler Message sendmessage与handlemessage obtainmessage
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相关推荐
- 多线程——主线程和子线程退出关系
分清两个概念 主线程和当前进程的关系:当前进程由主线程和若干个子线程组成. 若当前进程退出后,子线程也会跟着一起退出:若只是主线程退出,仍要分两种情况分析:实际上主线程退出后子线程的状态依赖于它所在的 ...
- Android之用Handler实现主线程和子线程互相通信以及子线程和子线程之间的通信
1.上代码 activity_main.xml文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/ ...
- Android之HandlerThread源码分析和简单使用(主线程和子线程通信、子线程和子线程通信)
1.先熟悉handler方式实现主线程和子线程互相通信方式,子线程和子线程的通信方式 如果不熟悉或者忘记了,请参考我的这篇博客 Android之用Handler实现主线程和子线程互相通信以及子 ...
- c++主线程等待子线程结束_简单明了的 Python 多线程来了 | 原力计划
作者 | 万里羊责编 | 王晓曼出品 | CSDN博客线程和进程计算机的核心是CPU,它承担了所有的计算任务,就像是一座工厂在时刻运行.如果工厂的资源有限,一次只能供一个车间来使用,也就是说当一个车间 ...
- 【多线程】学习记录七种主线程等待子线程结束之后在执行的方法
最近遇到一个问题需要主线程等待所有的子线程结束,才能开始执行,统计所有的子线程执行结果,返回,网上翻阅各种资料,最后记录一下,找到七种方案 第一种:while循环 对于"等待所有的子线程结束 ...
- java主线程控制子线程_CountDownLatch控制主线程等子线程执行完--Java多线程
1.[代码]CountDownLatch控制主线程等子线程执行完--Java多线程 package com.sihuatech.common; import java.util.concurrent. ...
- 主线程和子线程的区别,线程之间的通信
1.主线程来向子线程发送消息的方法 在平时写程序时,我们一般都是在子线程中向主线程发送消息,从而完成请求的处理,这个很常见,不用多说了.那么有时候,我们也可能碰到这样子的一种需求:需要主线程来向子线程 ...
- Java多线程之----主线程会等待子线程结束再结束么,怎么让主线程等待子线程结束呐?
首先给出结论: 主线程和子线程之间没有谁先谁后结束这种关联,它们只是各自负责自己的线程任务,如果该线程的任务结束了,该线程自然会结束运行. talk is cheap,show me the code ...
- java中子线程与主线程通信_Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息...
之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码: ...
最新文章
- 菜鸟也来学习ORACLE(1)_linux下安装oracle 11g
- 硬核!我的导师手写129页毕业论文,堪比打印!
- 如何在Java中将String转换为int?
- SpringMVC入门案例
- 算法与数据结构(part3)--数据结构概述
- cstring判断包含字符串_Python字符串方法之-解决判断问题
- nssl1298-网站计划【线段树】
- gcovr 安装_Kudu 1.8.0 编译安装配置
- 如何识别哭泣csdn_如何让敏感的孩子,不再那么敏感?不是溺爱,而是懂得这些方法...
- 题目:求100以内的全部素数,每行输出10个。1不是素数
- 计算机专业英语词汇1695词(35天记忆)
- java电商ERP源码 跨境电商ERP源码 ERP源码
- Android函数插桩,Android 代码插桩 ~ Misaki’s Blog
- python中计算ln和lg的方法
- velodyne+cartographer 2D构建栅格地图
- 容量 Byte、KB、MB、GB、TB、PB、EB、ZB、YB、NB、DB、CB、XB
- VOT, OTB——目标追踪的发展概况
- AOSP中make clean与make clobber的区别
- [JIRA] 从3.6.2旧版升级到新版6.0.8的详细过程
- html下拉式日历,C#实现日历样式的下拉式计算器