转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代码

  1. public class Activity2 extends Activity implements OnClickListener{
  2. Button button = null;
  3. TextView text = null;
  4. MyHandler mHandler = null;
  5. Thread thread ;
  6. @Override
  7. protected void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity1);
  10. button = (Button)findViewById(R.id.btn);
  11. button.setOnClickListener(this);
  12. text = (TextView)findViewById(R.id.content);
  13. }
  14. public void onClick(View v) {
  15. switch (v.getId()) {
  16. case R.id.btn:
  17. thread = new MyThread();
  18. thread.start();
  19. break;
  20. }
  21. }
  22. private class MyHandler extends Handler{
  23. public MyHandler(Looper looper){
  24. super(looper);
  25. }
  26. @Override
  27. public void handleMessage(Message msg) {//处理消息
  28. text.setText(msg.obj.toString());
  29. }
  30. }
  31. private class MyThread extends Thread{
  32. @Override
  33. public void run() {
  34. Looper curLooper = Looper.myLooper();
  35. Looper mainLooper = Looper.getMainLooper();
  36. String msg ;
  37. if(curLooper==null){
  38. mHandler = new MyHandler(mainLooper);
  39. msg = "curLooper is null";
  40. }else{
  41. mHandler = new MyHandler(curLooper);
  42. msg = "This is curLooper";
  43. }
  44. mHandler.removeMessages(0);
  45. Message m = mHandler.obtainMessage(1, 1, 1, msg);
  46. mHandler.sendMessage(m);
  47. }
  48. }
  49. }

这个没有问题,基本上三个对象的使用也很清楚,myHandler虽然是由子线程new出来的,但主线程持有引用,在我们的项目中不能用,因为我们几个线程属于不同的类,我尝试用下面的方法解决:

在IoHandler中new一个android的handler,参数为主线程的Looper:

Java代码

  1. new Handler(Looper.getMainLooper()).sendMessage(msg);

IoHandler所在的线程给主线程发送消息(looper是主线程的,消息也就放在主线程的消息队列里了)

但是在主线程的handleMessage方法中得不到消息,尝试失败。

那么怎么办呢,让IoHandler持有主线程的handler引用,具体做法有两种方式:

1.  参数传递,把主线程的handler通过参数传递的形式传到IoHandler中。

2. 静态变量,把主线程的handler申明为公共静态变量

Java代码

  1. public static Handler mainHandler;

这样在Iohandler中使用

Java代码

  1. welcomeActivity.mainHandler.sendMessage(msg);

这两种方式在主线程的  handleMessage的方法中都可以得到IoHandler发送的消息。

本人使用的是静态变量解决的,因为有好几个来实现通信,参数传递太麻烦。

那为什么我的第一种尝试是失败的呢,我是把消息放到主线程的消息队列了啊,这就要看android的一些实现机制了。

通过网络和android的api,本人的理解如下:

Looper是MessageQueue和Handler沟通的桥梁,Handler通过Looper把消息放入消息队列(MessageQueue),你想把消息发给谁,就把谁的looper作为参数传给Handler

Java代码

  1. 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不同线程间的通信的更多相关文章

  1. Handler实现线程间的通信2

    与Handler实现线程间的通信1反过来MainThread中向WorkerThread中发送消息

  2. Handler实现线程间的通信1

    通过Handler实现线程间的通信,在主线程当中实现Handler的handlerMessage()方法,在WorkerThread中通过Handler发送消息 Handler实现线程间的通信实例: ...

  3. 新建线程与UI线程间的通信

    现在用一个实例来演示一下自己的新建线程与UI线程间的通信. UI界面包含3个控件: 一个输入框,用来输入数字: 一个显示框,用来显示从2开始,到输入数字之间的所有质数: 一个按钮,点击后获取输入框输入 ...

  4. android 线程间的通信

    (转自:http://www.cnblogs.com/allin/archive/2010/05/19/1738800.html) andriod提供了 Handler 和 Looper 来满足线程间 ...

  5. Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)

    keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间).(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况. 本文主 ...

  6. iOS开发多线程篇—线程间的通信

    iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任 ...

  7. Java核心知识点学习----多线程并发之线程间的通信,notify,wait

    1.需求: 子线程循环10次,主线程循环100次,这样间隔循环50次. 2.实现: package com.amos.concurrent; /** * @ClassName: ThreadSynch ...

  8. java多线程详解(6)-线程间的通信wait及notify方法

    Java多线程间的通信 本文提纲 一. 线程的几种状态 二. 线程间的相互作用 三.实例代码分析 一. 线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种:(1). 产生(New) ...

  9. iOS边练边学--多线程NSOperation介绍,子类实现多线程的介绍(任务和队列),队列的取消、暂停(挂起)和恢复,操作依赖与线程间的通信

    一.NSOperation NSOperation和NSOperationQueue实现多线程的具体步骤 先将需要执行的操作封装到一个NSOperation对象中 然后将NSOperation对象添加 ...

随机推荐

  1. java Script 中的keyCode 和charCode

    其实很长一段时间,我都没有完全弄明白keyCode 和charCode ,自己也认真看过,但是就是理解不透彻,为了防止以后再出现混乱,写篇博客记录一下吧! 首先  在不同的浏览器中,他们有不同的说法哦 ...

  2. ASP.NET页面传值的几种方式

    页面传值是学习asp.net初期都会面临的一个问题,总的来说有页面传值. 存储对象传值.ajax.类.model.表单等!下面欧柏泰克和大家一起来看看asp.net页面传值方式一般有哪些?常用的较简单 ...

  3. UNIX/Linux进程间通信IPC---管道--全总结(实例入门)

    管道 一般,进程之间交换信息的方法只能是经由fork或exec传送打开文件,或者通过文件系统.而进程间相互通信还有其他技术——IPC(InterProcessCommunication) (因为不同的 ...

  4. 简单的webservice

    Hi,大家好! 今天主要和大家分享,如何搭建一个Web服务,做Android开发,不可避免会涉及到客户端开发,我们怎么样来实现一个服务端,怎么样来实现一个客户端,并相互传递数据.就算调用别人的服务时, ...

  5. 转:让ie6-8支持部分css3样式的方案

    我们都知道,IE浏览器暂不支持CSS3的一些属性.国外的工程师们,不安于此现状,他们总是尽量使用一些手段使IE浏览器也能支持CSS3属性,我觉得这些都是很有意义,很有价值的工作,可以推动整个技术领域的 ...

  6. Java学习之IO之File类一

    File的操作 package com.gh.file; import java.io.File; import java.io.IOException; /** * File操作 * @author ...

  7. large-scale analysis of malware downloaders

    http://www.christian-rossow.de/publications/downloaders-dimva12.pdf

  8. Cocos2d-x 精灵碰撞检測(方法二)

    将"Cocos2d-x 精灵碰撞检測(方法一)" update函数改动一下. 使用精灵boundingBox函数获取直接精灵边界框, 不用自己计算精灵矩形大小了,还比較精确,然后调 ...

  9. OpenStack导入镜像后Launch不起来的几个问题

    Dashboard上显示state为error 没有其他报错 用nova list找到虚拟机的id 然后nova show,可以得到fault详细信息 也可以查看下面两个log /var/log/no ...

  10. 增进离岸Java开发效率的10个提示

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/10-tips-offshore-java-effective Cygn ...