Android HandlerThread的使用及原理详解

一、HandlerThread的含义

HandlerThread能够新建拥有Looper的线程。这个Looper能够用来新建其他的Handler。(线程中的Looper)需要注意的是,新建的时候需要被回调。

二、HandlerThread的用法

一般情况下,我们会经常用Handler在子线程中更新UI线程,那是因为在主线程中有Looper循环,而HandlerThread新建拥有Looper的子线程又有什么用呢?

必然是执行耗时操作。举个例子,数据实时更新,我们每10秒需要切换一下显示的数据,如果我们将这种长时间的反复调用操作放到UI线程中,虽说可以执行,但是这样的操作多了之后,很容易会让UI线程卡顿甚至崩溃。

于是,就必须在子线程中调用这些了。
HandlerThread继承自Thread,一般适应的场景,便是集Thread和Handler之所长,适用于会长时间在后台运行,并且间隔时间内(或适当情况下)会调用的情况,比如上面所说的实时更新。

三、实现每2秒更新一下UI

public class MainActivity extends AppCompatActivity { private TextView tvMain; private HandlerThread mHandlerThread; //子线程中的handler private Handler mThreadHandler; //UI线程中的handler private Handler mMainHandler = new Handler(); //以防退出界面后Handler还在执行 private boolean isUpdateInfo; //用以表示该handler的常熟 private static final int MSG_UPDATE_INFO = 0x110; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvMain = (TextView) findViewById(R.id.tv_main); initThread(); } private void initThread() { mHandlerThread = new HandlerThread("check-message-coming"); mHandlerThread.start(); mThreadHandler = new Handler(mHandlerThread.getLooper()) { @Override public void handleMessage(Message msg) { update();//模拟数据更新 if (isUpdateInfo) mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO); } }; } private void update() { try { //模拟耗时 Thread.sleep(2000); mMainHandler.post(new Runnable() { @Override public void run() { String result = "每隔2秒更新一下数据:"; result += Math.random(); tvMain.setText(result); } }); } catch (InterruptedException e) { e.printStackTrace(); } } @Override protected void onResume() { super.onResume(); //开始查询 isUpdateInfo = true; mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO); } @Override protected void onPause() { super.onPause(); //停止查询 //以防退出界面后Handler还在执行 isUpdateInfo = false; mThreadHandler.removeMessages(MSG_UPDATE_INFO); } @Override protected void onDestroy() { super.onDestroy(); //释放资源 mHandlerThread.quit(); } }

四、HandlerThread 原理

public class HandlerThread extends Thread { int mPriority; int mTid = -1; Looper mLooper; public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } public HandlerThread(String name, int priority) { super(name); mPriority = priority; } protected void onLooperPrepared() { } @Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; } public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; } public boolean quit() { Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false; } public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; } public int getThreadId() { return mTid; } }

首先我们可以看到HandlerThread继承自Thread,因此在run()中的逻辑都是在子线程中运行的。

接下来就是两个关键的方法,run()和getLooper():
run()中可以看到是很简单的创建Looper以及让Looper工作的逻辑。
run()里面当mLooper创建完成后有个notifyAll(),getLooper()中有个wait(),这有什么用呢?因为的mLooper在一个线程中执行创建,而我们的handler是在UI线程中调用getLooper()初始化的。
也就是说,我们必须等到mLooper创建完成,才能正确的返回。getLooper();wait(),notify()就是为了解决这两个线程的同步问题。

时间: 2024-09-30 06:04:01

Android HandlerThread的使用及原理详解的相关文章

Android系统获取Root权限原理详解

android root权限破解分析 许多机友新购来的Android机器没有破解过Root权限,无法使用一些需要高权限的软件,以及进行一些高权限的操作,其实破解手机Root权限是比较简单及安全的,破解Root权限的原理就是在手机的/system/bin/或/system/xbin/目录下放置一个可执行文件"su",这是一个二进制文件,相当于电脑上的exe文件,仅仅在系统中置入这个"su"文件是不会给手机的软件或硬件造成任何故障. 下面的代码是android系统原版的

android universal image loader 缓冲原理详解

1. 功能介绍 1.1 Android Universal Image Loader Android Universal Image Loader 是一个强大的.可高度定制的图片缓存,本文简称为UIL. 简单的说 UIL 就做了一件事--获取图片并显示在相应的控件上. 1.2 基本使用 1.2.1 初始化 添加完依赖后在Application或Activity中初始化ImageLoader,如下: public class YourApplication extends Application

Android动态加载Activity原理详解_Android

activity的启动流程 加载一个Activity肯定不会像加载一般的类那样,因为activity作为系统的组件有自己的生命周期,有系统的很多回调控制,所以自定义一个DexClassLoader类加载器来加载插件中的Activity肯定是不可以的. 首先不得不了解一下activity的启动流程,当然只是简单的看一下,太详细的话很难研究清楚. 通过startActivity启动后,最终通过AMS进行跨进程回调到ApplicationThread的scheduleLaunchActivity,这时

Android动态加载Activity原理详解

activity的启动流程 加载一个Activity肯定不会像加载一般的类那样,因为activity作为系统的组件有自己的生命周期,有系统的很多回调控制,所以自定义一个DexClassLoader类加载器来加载插件中的Activity肯定是不可以的. 首先不得不了解一下activity的启动流程,当然只是简单的看一下,太详细的话很难研究清楚. 通过startActivity启动后,最终通过AMS进行跨进程回调到ApplicationThread的scheduleLaunchActivity,这时

Android热修复技术原理详解与升级探索

在2017云栖大会-上海峰会上手机淘宝资深无线开发工程师甘晓霖(万壑)作了题为<Android热修复技术原理详解与升级探索>的分享,如何实现客户端与开发节奏最快同步,阿里云为此开发了移动热修复框架Sophix.它在代码修复.资源修复.SO库修复中都展示了极高的能力,在于其他竞品的对比中,Sophix展示出来极大的优势,并且非常容易上手.

Android消息处理机制Looper和Handler详解_Android

Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理. Handler:处理者,负责Message的发送及处理.使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等. MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行.当然,存放Message并非实际意义的保存,而是将Message以链表的方

Win32应用程序(SDK)设计原理详解_C 语言

一般来说所谓的Win32应用程序开发,就是在C语言的层面上,直接使用Win32 API(Application Programming Interface:系统开放出来,给程序员使用的接口.)来开发Windows应用程序或者系统程序.虽然现在直接用Win32 API开发应用程序的人已经不多了,但是深入理解Windows系统程序设计原理,仍然是成为Windows开发高手的必经之路. 所谓的Win32,其实是一个API规范,与UNIX系统编程接口标准POSIX是相对应的.下面是进行直接的WIN32

Android 打包三种方式实例详解

Android 打包三种方式实例详解 前言: 现在市场上很多app应用存在于各个不同的渠道,大大小小几百个,当我们想要在发布应用之后统计各个渠道的用户下载量,我们就要进行多渠道打包. 01.应用的打包签名什么是打包? 打包就是根据签名和其他标识生成安装包. 签名是什么? 1.在android应用文件(apk)中保存的一个特别字符串 2.用来标识不同的应用开发者:开发者A,开发者B 3.一个应用开发者开发的多款应用使用同一个签名 就好比是一个人写文章,签名就相当于作者的署名. 如果两个应用都是一个

Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)

  [Android布局学习系列]   1.Android 布局学习之--Layout(布局)详解一   2.Android 布局学习之--Layout(布局)详解二(常见布局和布局参数)   3.Android 布局学习之--LinearLayout的layout_weight属性   4.Android 布局学习之--LinearLayout属性baselineAligned的作用及baseline      Layout Parameters(布局参数):            在XML文