Handler不同线程间的通信
转http://www.iteye.com/problems/69457
Activity启动后点击一个界面按钮后会开启一个服务(暂定为padService),在padService中会启动一个线程(暂定为Thread-3)发起Socket连接。我们项目中使用mina作为socket通信框架,用过mina的同志们应该熟悉,Thread-3只是负责监听,具体的消息处理是另外的线程。在我们的IoHandler中处理消息,现在的问题是,我需要在IoHander的sessionOpened方法中给Activity一个消息去更新UI界面,这个就涉及到不同线程间的通信了。
网上搜索后,在android中线程间通信使用Handler,Looper,Message这几个对象(不熟悉这些概念的同志们请自己查下)。
这是网上的一个使用例子:
Java代码
- public class Activity2 extends Activity implements OnClickListener{
- Button button = null;
- TextView text = null;
- MyHandler mHandler = null;
- Thread thread ;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity1);
- button = (Button)findViewById(R.id.btn);
- button.setOnClickListener(this);
- text = (TextView)findViewById(R.id.content);
- }
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.btn:
- thread = new MyThread();
- thread.start();
- break;
- }
- }
- private class MyHandler extends Handler{
- public MyHandler(Looper looper){
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {//处理消息
- text.setText(msg.obj.toString());
- }
- }
- private class MyThread extends Thread{
- @Override
- public void run() {
- Looper curLooper = Looper.myLooper();
- Looper mainLooper = Looper.getMainLooper();
- String msg ;
- if(curLooper==null){
- mHandler = new MyHandler(mainLooper);
- msg = "curLooper is null";
- }else{
- mHandler = new MyHandler(curLooper);
- msg = "This is curLooper";
- }
- mHandler.removeMessages(0);
- Message m = mHandler.obtainMessage(1, 1, 1, msg);
- mHandler.sendMessage(m);
- }
- }
- }
这个没有问题,基本上三个对象的使用也很清楚,myHandler虽然是由子线程new出来的,但主线程持有引用,在我们的项目中不能用,因为我们几个线程属于不同的类,我尝试用下面的方法解决:
在IoHandler中new一个android的handler,参数为主线程的Looper:
Java代码
- new Handler(Looper.getMainLooper()).sendMessage(msg);
IoHandler所在的线程给主线程发送消息(looper是主线程的,消息也就放在主线程的消息队列里了)
但是在主线程的handleMessage方法中得不到消息,尝试失败。
那么怎么办呢,让IoHandler持有主线程的handler引用,具体做法有两种方式:
1. 参数传递,把主线程的handler通过参数传递的形式传到IoHandler中。
2. 静态变量,把主线程的handler申明为公共静态变量
Java代码
- public static Handler mainHandler;
这样在Iohandler中使用
Java代码
- welcomeActivity.mainHandler.sendMessage(msg);
这两种方式在主线程的 handleMessage的方法中都可以得到IoHandler发送的消息。
本人使用的是静态变量解决的,因为有好几个来实现通信,参数传递太麻烦。
那为什么我的第一种尝试是失败的呢,我是把消息放到主线程的消息队列了啊,这就要看android的一些实现机制了。
通过网络和android的api,本人的理解如下:
Looper是MessageQueue和Handler沟通的桥梁,Handler通过Looper把消息放入消息队列(MessageQueue),你想把消息发给谁,就把谁的looper作为参数传给Handler
Java代码
- newHandler(Looper looper);
Looper把消息放入消息队列,并广播消息,这个不太好理解,我举例如下:
主线程的Handler我们这样定义:Handler mainHandler = new Handler(); 如果Handler没有参数,默认为当前线程的Looper
子线程的Handler我们这样定义: Handler subHandler = newHandler(Looper.getMainLooper()); 参数为主线程的Looper
这样两个线程都会把消息放入主线程的消息队列里了。
现在mainHandler.sendMessage(), 消息进入主线程的消息队列,Looper广播消息,其实就是调用mainHandler的dispatchMessage方法,所有持有mianHandler引用的类都可以收到消息,注意啊,现在subHandler并不能接受到消息,因为Looper并没有调用subHandler的dispatchMessage方法,所以应该这样理解广播,A发送消息,那么A的Looper就调用A的dispatchMessage方法,别的B,C, D虽然也是A的Looper,但没有A的引用,所以B,C,D是接受不到消息的,如果B, C,D持有A的引用,但B,C,D不用A的Looper,那么也是接受不到消息的。这点在开发时要特别注意。
以上是我在使用Looper, Handler ,Message中的一些问题,可能有理解错的地方,请大大们指出来。
我的疑惑是难道子线程必须持有主线程的引用才可以给主线程发送消息吗?要知道我们的子线程并不一定和主线程一个类,可能在别的类中,这个引用传递实在太麻烦了,期望有更好的解决方式。
Handler不同线程间的通信的更多相关文章
- Handler实现线程间的通信2
与Handler实现线程间的通信1反过来MainThread中向WorkerThread中发送消息
- Handler实现线程间的通信1
通过Handler实现线程间的通信,在主线程当中实现Handler的handlerMessage()方法,在WorkerThread中通过Handler发送消息 Handler实现线程间的通信实例: ...
- 新建线程与UI线程间的通信
现在用一个实例来演示一下自己的新建线程与UI线程间的通信. UI界面包含3个控件: 一个输入框,用来输入数字: 一个显示框,用来显示从2开始,到输入数字之间的所有质数: 一个按钮,点击后获取输入框输入 ...
- android 线程间的通信
(转自:http://www.cnblogs.com/allin/archive/2010/05/19/1738800.html) andriod提供了 Handler 和 Looper 来满足线程间 ...
- Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)
keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间).(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况. 本文主 ...
- iOS开发多线程篇—线程间的通信
iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任 ...
- Java核心知识点学习----多线程并发之线程间的通信,notify,wait
1.需求: 子线程循环10次,主线程循环100次,这样间隔循环50次. 2.实现: package com.amos.concurrent; /** * @ClassName: ThreadSynch ...
- java多线程详解(6)-线程间的通信wait及notify方法
Java多线程间的通信 本文提纲 一. 线程的几种状态 二. 线程间的相互作用 三.实例代码分析 一. 线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种:(1). 产生(New) ...
- iOS边练边学--多线程NSOperation介绍,子类实现多线程的介绍(任务和队列),队列的取消、暂停(挂起)和恢复,操作依赖与线程间的通信
一.NSOperation NSOperation和NSOperationQueue实现多线程的具体步骤 先将需要执行的操作封装到一个NSOperation对象中 然后将NSOperation对象添加 ...
随机推荐
- ListView列表项
方法,在xml文件中添加一个ListView,然后在MainActivity中 private ListView listView; private ArrayAdapter<String> ...
- OCP-1Z0-053-V13.02-712新题
Why does the number of blocks for the table remain the sale after the shrink operation? A.Because ...
- JS 获取星期几的四种写法
今天是星期几的4种JS代码写法,有需要的朋友可以参考一下 第一种写法 复制代码代码如下: var str = ""; var week = new Date().getDay() ...
- "No appenders found for logger" and "Please configure log4j properly"
Why do I see a warning about "No appenders found for logger" and "Please configure lo ...
- python Unable to find vcvarsall.bat 错误
今天遇到了这个方面的问题,目前找到两种办法.一种是换编译器如mingw,另一种是装vc.第一种方法没成功,现在正在等第二种. 第一种: 首先安装MinGW: 把MinGW的路径添加到环境变量path中 ...
- iOS中谓词的使用
Cocoa提供了一个类NSPredicate类,该类主要用于指定过滤器的条件,该对象可以准确的描述所需条件,对每个对象通过谓词进行筛选,判断是否与条件相匹配.谓词表示计算真值或假值的函数.在cocoa ...
- Java数据类型BooleanDemo
- Unity Notes调制粒子系统的颗粒的最大数目
Unity该粒子系统是很容易使用.这样的问题是在实际的过程中遇到的:以控制的粒子系统组件的动态需要可产生颗粒的最大数目. 看doc他说,有maxParticles控制.却没有这个开放的參数.仅仅能通过 ...
- MAC安裝《Genymotion Android模擬器》大玩Android APP (神魔之塔)
链接地址:http://www.minwt.com/mac/10083.html/comment-page-2 MAC» 智慧型裝罝» Android | 2014/02/12 Android是一個開 ...
- BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛( floyd + 二分答案 + 最大流 )
一道水题WA了这么多次真是.... 统考终于完 ( 挂 ) 了...可以好好写题了... 先floyd跑出各个点的最短路 , 然后二分答案 m , 再建图. 每个 farm 拆成一个 cow 点和一个 ...