`
anson_xu
  • 浏览: 513862 次
  • 性别: Icon_minigender_1
  • 来自: 惠州
社区版块
存档分类

andriod提供了 Handler 和 Looper 来满足线程间的通信

阅读更多

Android----Thread+Handler 线程 消息循环( 转载)

近来找了一些关于android 线程间通信的资料,整理学习了一下,并制作了一个简单的例子。

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

Android ,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper ,这个事android 的新 概念。我们的主线程(UI 线程)就是一个消息循环的线程。针对这种消息循环的机制,我们引入一个新的机制Handle ,我们有消息循环,就要往消息循环里 面发送相应的消息,自定义消息一般都会有自己对应的处理,消息的发送和清除,消息的的处理,把这些都封装在Handle 里面,注意Handle 只是针对那 些有Looper 的线程,不管是UI 线程还是子线程,只要你有Looper ,我就可以往你的消息队列里面添加东西,并做相应的处理。
但是这里还有一点,就是只要是关于UI 相关的东西,就不能放在子线程中,因为子线程是不能操作UI 的,只能进行数据、系统等其他非UI 的操作。
   在Android ,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper ,这个是android 的新概 念。我们的主线程(UI 线程)就是一个消息循环的线程。针对这种消息循环的机制,我们引入一个新的机制Handler ,我们有消息循环,就要往消息循环里 面发送相应的消息,自定义消息一般都会有自己对应的处理,消息的发送和清除,把这些都封装在Handler 里面,注意Handler 只是针对那 些有Looper 的线程,不管是UI 线程还是子线程,只要你有Looper ,我就可以往你的消息队列里面添加东西,并做相应的处理。

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


  一个Handler 的创建它就会被绑定到这个线程的消息队列中,如果是在主线程创建的,那就不需要写代码来创建消息队列了,默认的消息队列会在主线程被创建。但是如果是在子线程的话,就必须在创建Handler 之前先初始化线程的消息队列。如下面的代码:

Java 代码

  1. class ChildThread extends Thread {  
  2.   
  3.     public void run() {  
  4.   
  5.         /* 
  6.          *  创建 handler 前先初始化Looper. 
  7.          */  
  8.         Looper.prepare();  
  9.   
  10.         /* 
  11.          *  在子线程创建handler ,所以会绑定到子线程的消息队列中 
  12.          * 
  13.          */  
  14.         mChildHandler = new Handler() {  
  15.   
  16.             public void handleMessage(Message msg) {  
  17.   
  18.                 /* 
  19.                  * Do some expensive operations there. 
  20.                  */  
  21.             }  
  22.         };  
  23.   
  24.         /* 
  25.          *  启动该线程的消息队列 
  26.          */  
  27.         Looper.loop();  
  28.     }  
  29. }  

class ChildThread extends Thread {

 

    public void run() {

 

        /*

         * 创建 handler 前先初始化Looper.

         */

        Looper.prepare();

 

        /*

         * 在子线程创建handler ,所以会绑定到子线程的消息队列中

         *

         */

        mChildHandler = new Handler() {

 

            public void handleMessage(Message msg) {

 

                /*

                 * Do some expensive operations there.

                  */

            }

        };

 

        /*

         * 启动该线程的消息队列

         */

        Looper.loop();

    }

}

 



Handler 收到消息后,就会运行handleMessage(…) 的回调函数,可以在里面做一些耗时的操作。




最后完成了操作要结束子线程时,记得调用quit() 来结束消息循环队列。

mChildHandler.getLooper().quit();



下面是一个线程间通信的小例子:

Java 代码

  1. /** 
  2.  *  
  3.  * @author allin.dev  
  4.  * http://allin.cnblogs.com 
  5.  *  
  6.  */  
  7. public class MainThread extends Activity {  
  8.   
  9.     private static final String TAG = "MainThread";  
  10.     private Handler mMainHandler, mChildHandler;  
  11.     private TextView info;  
  12.     private Button msgBtn;  
  13.   
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.main);  
  18.   
  19.         info = (TextView) findViewById(R.id.info);  
  20.         msgBtn = (Button) findViewById(R.id.msgBtn);  
  21.   
  22.         mMainHandler = new Handler() {  
  23.   
  24.             @Override  
  25.             public void handleMessage(Message msg) {  
  26.                 Log.i(TAG, "Got an incoming message from the child thread - "  
  27.                         + (String) msg.obj);  
  28.                 //  接收子线程的消息  
  29.                 info.setText((String) msg.obj);  
  30.             }  
  31.   
  32.         };  
  33.   
  34.         new ChildThread().start();  
  35.           
  36.           
  37.         msgBtn.setOnClickListener(new OnClickListener() {  
  38.   
  39.             @Override  
  40.             public void onClick(View v) {  
  41.                   
  42.                 if (mChildHandler != null) {  
  43.                       
  44.                     // 发送消息给子线程  
  45.                     Message childMsg = mChildHandler.obtainMessage();  
  46.                     childMsg.obj = mMainHandler.getLooper().getThread().getName() + " says Hello";  
  47.                     mChildHandler.sendMessage(childMsg);  
  48.                       
  49.                     Log.i(TAG, "Send a message to the child thread - " + (String)childMsg.obj);  
  50.   
  51.   
  52.                 }  
  53.             }  
  54.         });  
  55.   
  56.     }  
  57.   
  58.     public void onDestroy() {  
  59.       super.onDestroy();  
  60.         Log.i(TAG, "Stop looping the child thread's message queue");  
  61.   
  62.         mChildHandler.getLooper().quit();  
  63.     }  
  64.   
  65.     class ChildThread extends Thread {  
  66.   
  67.         private static final String CHILD_TAG = "ChildThread";  
  68.   
  69.         public void run() {  
  70.             this.setName("ChildThread");  
  71.   
  72.             // 初始化消息循环队列,需要在Handler 创建之前  
  73.             Looper.prepare();  
  74.   
  75.             mChildHandler = new Handler() {  
  76.                 @Override  
  77.                 public void handleMessage(Message msg) {  
  78.                      Log.i(CHILD_TAG, "Got an incoming message from the main thread - " + (String)msg.obj);  
  79.   
  80.   
  81.                     try {  
  82.   
  83.                         // 在子线程中可以做一些耗时的工作  
  84.                         sleep(100);  
  85.   
  86.                         Message toMain = mMainHandler.obtainMessage();  
  87.                         toMain.obj = "This is " + this.getLooper().getThread().getName() +  
  88.                                     ".  Did you send me \"" + (String)msg.obj + "\"?";  
  89.   
  90.                         mMainHandler.sendMessage(toMain);  
  91.   
  92.                         Log.i(CHILD_TAG, "Send a message to the main thread - " + (String)toMain.obj);  
  93.   
  94.                     } catch (InterruptedException e) {  
  95.                         // TODO Auto-generated catch block  
  96.                         e.printStackTrace();  
  97.                     }  
  98.                 }  
  99.   
  100.             };  
  101.   
  102.             Log.i(CHILD_TAG, "Child handler is bound to - "+ mChildHandler.getLooper().getThread().getName());  
  103.   
  104.             // 启动子线程消息循环队列  
  105.             Looper.loop();  
  106.         }  
  107.     }  
  108. }  

 

分享到:
评论

相关推荐

    andriod多线程通信handler方法

    为了防止UI线程被阻塞,Android引入了Handler、Looper和Message机制来实现线程间通信,尤其是主线程(UI线程)与工作线程之间的交互。"andriod多线程通信handler方法"这个主题正是关注这一核心概念。 首先,我们...

    Android 线程开发 开发实例

    andriod提供了 Handler 和 Looper 来满足线程间的通信。例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的。 在Android,这里的线程分为有...

    Handler使用

    在Android开发中,`Handler`是一个至关重要的组件,主要用于解决线程间的通信问题,尤其是在UI线程和其他工作线程之间。本篇文章将深入探讨`Handler`的使用方法,包括其基本概念、工作原理以及如何避免内存泄露和...

    andriod多任务多线程下载

    如果DownloadManager无法满足需求,开发者可以自定义Service来实现多线程下载。通常会创建一个ThreadPoolExecutor,配置合适的线程池大小,然后将每个下载任务作为一个Runnable提交到线程池中执行。 5. **多线程...

    多线程断点续传带进度条

    在实际开发中,还可以考虑使用第三方库如Volley、OkHttp或Retrofit等,它们提供了更方便的网络请求和下载管理功能,可以简化多线程和断点续传的实现。 综合以上知识点,我们可以构建一个功能完善的多线程断点续传...

    android 2.3以后的socket注意

    从Android 2.3(Gingerbread)版本开始,为了更好地管理和优化系统资源,特别是考虑到多线程和网络操作的复杂性,Google引入了一些重要的变化,以确保Socket连接的正确性和效率。这些变化主要涉及线程管理和权限控制...

    android 消息机制

    在Android系统中,消息机制是实现线程间通信的关键组件,尤其对于UI线程与后台线程之间的交互至关重要。这个机制主要包括Handler、Message、Looper和MessageQueue四个核心组件。接下来,我们将深入探讨这些组件以及...

    Android多线程断点下载案例

    在实际开发中,我们可以使用Android提供的DownloadManager服务,它已经内置了多线程和断点续传功能,但若需要自定义更复杂的逻辑,如限制并发线程数、动态调整下载速度等,就需要自己实现多线程断点下载逻辑。...

    安卓Andriod源码——演化理解异步加载图片.zip

    - Handler/Looper/Message:Android消息传递机制,用于在不同线程间通信。 - AsyncTask:Android提供的轻量级异步任务类,简化了在主线程和工作线程间的操作。 3. **Android源码中的异步加载图片**: - `...

    Android studio 提示框Toast 弹出框AlertDialog 多种提示方法

    Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { //放在UI线程弹Toast Toast.makeText(Setting.this, 正在更新请稍后, Toast.LENGTH_...

    andriod小游戏

    Android提供了Handler、Looper和Runnable等机制来实现线程间的通信。 游戏中的动画效果也是关键部分。Android提供了多种方式实现动画,如Tween动画、帧动画以及属性动画。通过这些,你可以让角色动起来,或者实现...

    安卓Andriod源码——安卓视音频播放测试工程.zip

    使用Handler、Looper和Runnable等机制来实现线程间的通信和任务调度。 6. **权限管理**:播放本地或网络上的媒体文件可能需要请求相应的权限,例如READ_EXTERNAL_STORAGE用于读取外部存储中的媒体文件,INTERNET...

    andriod入门的一些资料

    10. **多线程与异步处理**:AsyncTask、Handler、Looper、ThreadPoolExecutor等异步处理机制,理解主线程与子线程的交互。 11. **网络编程**:HTTP请求库的使用,如OkHttp、Retrofit,以及如何处理JSON数据。 12. ...

    andriod stdio获取zigbee采集的数据

    6. **事件驱动编程**:使用Android的Handler和Looper机制,或者现代的RxJava库,可以有效地处理异步数据流,确保UI线程不被阻塞。 7. **异常处理**:考虑到无线通信的不稳定性和硬件故障,需要在代码中添加适当的...

    andriod开发技巧.

    同时,理解并运用Android的异步机制,如Handler、Looper和Runnable,以避免阻塞主线程。 网络编程在许多应用中占据重要地位。学习使用HttpURLConnection、OkHttp或者Volley库进行网络请求,理解JSON解析,并能处理...

    《Andriod应用开发揭秘》源码

    - 13141516.rar可能讲解了Android中的线程管理,如Handler、Looper和AsyncTask,以及如何避免UI线程阻塞。 6. **数据存储** - Android提供了多种数据存储方式,包括SharedPreferences、SQLite数据库、...

    安卓Andriod源码——串口开发的demo,里面包含JNI文件.zip

    7. **线程管理**:由于串口通信通常是异步的,因此在Android应用中,我们需要考虑线程安全问题,通常使用Handler、Looper或AsyncTask等机制来处理串口事件。 8. **异常处理**:串口通信可能会遇到各种异常,如设备...

    Andriod使用多线程实现轮播图片

    在Android开发中,实现轮播图效果是一种常见的需求...总之,Android中实现多线程轮播图的关键在于合理利用子线程进行耗时操作,并通过`Handler`与主线程通信。同时,注意性能优化和用户体验,确保图片加载快速且流畅。

    安卓Andriod源码——边下载边播music.zip

    Android提供了Handler、Looper和ThreadPool等机制来处理多线程。通常,我们会创建一个后台线程专门负责下载,主线程则负责播放控制。 4. **缓冲区管理:**为了保证流畅播放,需要在内存中设立缓冲区。当下载的数据...

Global site tag (gtag.js) - Google Analytics