Android应用程序线程消息循环模型分析(2)

简介:

  2. 应用程序子线程消息循环模型

        在Java框架中,如果我们想在当前应用程序中创建一个子线程,一般就是通过自己实现一个类,这个类继承于Thread类,然后重载Thread类的run函数,把我们想要在这个子线程执行的任务都放在这个run函数里面实现。最后实例这个自定义的类,并且调用它的start函数,这样一个子线程就创建好了,并且会调用这个自定义类的run函数。但是当这个run函数执行完成后,子线程也就结束了,它没有消息循环的概念。

        前面说过,有时候我们需要在应用程序中创建一些常驻的子线程来不定期地执行一些计算型任务,这时候就可以考虑使用Android系统提供的HandlerThread类了,它具有创建具有消息循环功能的子线程的作用。

        HandlerThread类实现在frameworks/base/core/java/android/os/HandlerThread.java文件中,这里我们通过使用情景来有重点的分析它的实现。

        在前面一篇文章Android系统默认Home应用程序(Launcher)的启动过程源代码分析中,我们分析了Launcher的启动过程,其中在Step 15(LauncherModel.startLoader)和Step 16(LoaderTask.run)中,Launcher会通过创建一个HandlerThread类来实现在一个子线程加载系统中已经安装的应用程序的任务:

  1. public class LauncherModel extends BroadcastReceiver {  
  2.     ......  
  3.   
  4.     private LoaderTask mLoaderTask;  
  5.   
  6.     private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");  
  7.     static {  
  8.         sWorkerThread.start();  
  9.     }  
  10.     private static final Handler sWorker = new Handler(sWorkerThread.getLooper());  
  11.   
  12.     ......  
  13.   
  14.     public void startLoader(Context context, boolean isLaunching) {    
  15.         ......    
  16.   
  17.         synchronized (mLock) {    
  18.             ......    
  19.   
  20.             // Don't bother to start the thread if we know it's not going to do anything    
  21.             if (mCallbacks != null && mCallbacks.get() != null) {    
  22.                 ......  
  23.   
  24.                 mLoaderTask = new LoaderTask(context, isLaunching);    
  25.                 sWorker.post(mLoaderTask);    
  26.             }    
  27.         }    
  28.     }    
  29.   
  30.     ......  
  31.   
  32.     private class LoaderTask implements Runnable {    
  33.         ......    
  34.   
  35.         public void run() {    
  36.             ......    
  37.   
  38.             keep_running: {    
  39.                 ......    
  40.   
  41.                 // second step    
  42.                 if (loadWorkspaceFirst) {    
  43.                     ......    
  44.                     loadAndBindAllApps();    
  45.                 } else {    
  46.                     ......    
  47.                 }    
  48.   
  49.                 ......    
  50.             }    
  51.   
  52.             ......    
  53.         }    
  54.   
  55.         ......    
  56.     }   
  57.   
  58.     ......  
  59. }  

        在这个LauncherModel类中,首先创建了一个HandlerThread对象:

  1. private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");  

        接着调用它的start成员函数来启动一个子线程:

  1. static {  
  2.     sWorkerThread.start();  
  3. }  

        接着还通过这个HandlerThread对象的getLooper函数来获得这个子线程中的消息循环对象,并且使用这个消息循环创建对象来创建一个Handler:

  1. private static final Handler sWorker = new Handler(sWorkerThread.getLooper());  

        有了这个Handler对象sWorker之后,我们就可以往这个子线程中发送消息,然后在处理这个消息的时候执行加载系统中已经安装的应用程序的任务了,在startLoader函数中:

  1. mLoaderTask = new LoaderTask(context, isLaunching);    
  2. sWorker.post(mLoaderTask);    

        这里的mLoaderTask是一个LoaderTask对象,它实现了Runnable接口,因此,可以把这个LoaderTask对象作为参数传给sWorker.post函数。在sWorker.post函数里面,会把这个LoaderTask对象封装成一个消息,并且放入这个子线程的消息队列中去。当这个子线程的消息循环处理这个消息的时候,就会调用这个LoaderTask对象的run函数,因此,我们就可以在LoaderTask对象的run函数中通过调用loadAndBindAllApps来执行加载系统中已经安装的应用程序的任务了。

 

        了解了HanderThread类的使用方法之后,我们就可以重点地来分析它的实现了:

  1. public class HandlerThread extends Thread {  
  2.     ......  
  3.     private Looper mLooper;  
  4.   
  5.     public HandlerThread(String name) {  
  6.         super(name);  
  7.         ......  
  8.     }  
  9.   
  10.     ......  
  11.   
  12.     public void run() {  
  13.         ......  
  14.         Looper.prepare();  
  15.         synchronized (this) {  
  16.             mLooper = Looper.myLooper();  
  17.             ......  
  18.         }  
  19.         ......  
  20.         Looper.loop();  
  21.         ......  
  22.     }  
  23.   
  24.     public Looper getLooper() {  
  25.         ......  
  26.         return mLooper;  
  27.     }  
  28.   
  29.     ......  
  30. }  

        首先我们看到的是,HandlerThread类继承了Thread类,因此,通过它可以在应用程序中创建一个子线程,其次我们看到在它的run函数中,会进入一个消息循环中,因此,这个子线程可以常驻在应用程序中,直到它接收收到一个退出消息为止。

 

        在run函数中,首先是调用Looper类的静态成员函数prepare来准备一个消息循环对象:

  1. Looper.prepare();  

        然后通过Looper类的myLooper成员函数将这个子线程中的消息循环对象保存在HandlerThread类中的成员变量mLooper中:

  1. mLooper = Looper.myLooper();  

        这样,其它地方就可以方便地通过它的getLooper函数来获得这个消息循环对象了,有了这个消息循环对象后,就可以往这个子线程的消息队列中发送消息,通知这个子线程执行特定的任务了。

 

        最在这个run函数通过Looper类的loop函数进入消息循环中:

  1. Looper.loop();  

        这样,一个具有消息循环的应用程序子线程就准备就绪了。

 

        HandlerThread类的实现虽然非常简单,当然这得益于Java提供的Thread类和Android自己本身提供的Looper类,但是它的想法却非常周到,为应用程序开发人员提供了很大的方便。





本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966878,如需转载请自行联系原作者
目录
相关文章
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
611 4
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
263 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
深入探索Android与iOS系统安全性的对比分析
在当今数字化时代,移动操作系统的安全已成为用户和开发者共同关注的重点。本文旨在通过比较Android与iOS两大主流操作系统在安全性方面的差异,揭示两者在设计理念、权限管理、应用审核机制等方面的不同之处。我们将探讨这些差异如何影响用户的安全体验以及可能带来的风险。
200 21
|
6月前
|
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
180 15
Android 系统缓存扫描与清理方法分析
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文深入探讨了这两个平台的开发环境,从编程语言、开发工具到用户界面设计等多个角度进行比较。通过实际案例分析和代码示例,我们旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和个人偏好做出明智的选择。无论你是初涉移动开发领域的新手,还是寻求跨平台解决方案的资深开发者,这篇文章都将为你提供宝贵的信息和启示。
85 8
|
4月前
|
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
143 4

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等