转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. 「OC」构造方法和分类

    一.构造方法 (一)构造方法的调用 创建一个可用的对象:Person *p=[Person new]; new方法实际上是分为两步来创建一个对象: 1)使用+alloc方法来分配存储空间(返回分配的对 ...

  2. BZOJ 1692: [Usaco2007 Dec]队列变换( 贪心 )

    数据 n <= 30000 , 然后 O( n² ) 的贪心也过了..... USACO 数据是有多弱啊 = = ( ps : BZOJ 1640 和此题一模一样 , 双倍经验 ) ------ ...

  3. UIWebvView 解决onClick 延迟相应问题

    在使用 UIWebView 的过程中, 发现 onClick 触发需要等待300-500ms, Google了一下, 发现是因为ScrollView 在等待doubleTap, 所以有延迟 使用如下代 ...

  4. Ecmall系统自带的分页功能使用

    在控制器如果没有定义相关模型,直接使用sql语句的话,直接使用如下语句. 即: public $db; $this->db = &db(); //然后开始使用分页类 $sql='sele ...

  5. Python网络编程——修改套接字发送和接收的缓冲区大小

    很多情况下,默认的套接字缓冲区大小可能不够用.此时,可以将默认的套接字缓冲区大小改成一个更合适的值. 1. 代码 # ! /usr/bin/env python # -*- coding: utf-8 ...

  6. 64位win8 配置Apache2.4+mod_msgi4.4.21+django1.8.6+python3.4

    学习了很多前人分享的资料,整理如下: 安装步骤: 一.安装python3.4        下载 python-3.4.3.amd64.msi 直接安装         地址:https://www. ...

  7. poj 1715 Hexadecimal Numbers 排列组合

    /** 大意: 给定16进制数的16个字母,,求第k大的数,,要求数的长度最大为8.,并且每个数互不相同. 思路: 从高到低挨个枚举,每一位能组成的排列数 ,拿最高位来说,能做成的排列数为15*A(1 ...

  8. (IOS)CoreLocation 和 MapKit 的应用

    CoreLocation是控制GPS硬件获取地理坐标信息的系统类库,而MapKit是系统地图的工具包,将两者结合使用可以实现不同的地图功能. 1.CoreLocation 在CoreLocation中 ...

  9. notify()、notifyAll()和wait()

    看到一道面试题,写一个多线程程序,交替输出1.2.1.2…… 先写下程序: /** * Created by Andrew on 2015/10/28. */ public class OutputT ...

  10. VC问题 IntelliSense:“没有可用的附加信息”,[请参见“C++项目 IntelliSense 疑难解答”,获得进一步的帮助]

    当出现以上的问题时,若按照网上所说的解决方法: 1.安装VA(Visual_AssistX) 2.安装Microsoft SQL Server Compact 3.5 3.更改设置“工具-选项-文本编 ...