Android HandlerThread案例详解
时间:2022-06-17 08:35:41|栏目:Android代码|点击: 次
HandlerThread 顾名思义就是一种可以使用 Handler 的 Thread。日常开发中我们经常会通过创建一个 Thread 去执行任务,有多个任务就多创建几个线程实现,这时候可能出现线程同步的问题。不过有时候我们并不需要很强的并发性,只需保证按照顺序地执行各个任务即可,有什么好办法实现呢?第一反应想到的可能是通过 Executors.newSingleThreadExecutor() 方法来创建一个 SingleThreadExecutor,来统一所有的任务到一个线程中,然后按顺序执行。其实,除了这个方法之外,HandlerThread 也可以实现。
简单使用
首先创建一个 HandlerThreadActivity
public class HandlerThreadActivity extends BaseActivity { private static final String TAG = "HandlerThreadActivity"; private Button mStartBtn; private Handler mHandler; private HandlerThread mHandlerThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler_thread); mStartBtn = findViewById(R.id.start_btn); mHandlerThread = new HandlerThread("THREAD_NAME"); mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mStartBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mHandler.post(new Runnable() { @Override public void run() { Log.d(TAG, Thread.currentThread().getId() + " " + String.valueOf((Looper.myLooper() == Looper.getMainLooper())) + " 任务:" + this.hashCode()); SystemClock.sleep(3000); } }); } }); } @Override protected void onDestroy() { super.onDestroy(); mHandlerThread.quit(); } }
快速三击按钮,打印日志如下:
可以发现,三次不同的任务按开始的顺序执行,而且是运行在子线程中,那到底是怎么实现的呢?
源码解析
public class HandlerThread extends Thread { int mPriority; int mTid = -1; Looper mLooper; private @Nullable Handler mHandler; 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() { // 获取线程 id mTid = Process.myTid(); //构建一个 Looper Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } //设置线程优先级 Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); // Looper 循环 mTid = -1; } // 获取当前线程的 Looper, public Looper getLooper() { if (!isAlive()) { return null; } synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; } /** * @return a shared {@link Handler} associated with this thread * @hide 方法隐藏掉,无法调用 */ @NonNull public Handler getThreadHandler() { if (mHandler == null) { mHandler = new Handler(getLooper()); } return mHandler; } //线程退出方法,主要是调用 Looper.quit() 方法,不然一直在循环 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; } }
通读下来,如果熟悉 Handler 原理的同学大概就明白 HandlerThread 的机制了:
- HandlerThread 运行 start() 方法,回调 run() 方法。
- 在 run() 方法中通过 Looper.prepare() 来创建消息队列,并通过 Looper.looper() 方法来开启消息循环。
- 由于 Loop.loop() 是一个死循环,导致 run() 也是无线循环,因此当我们不需要使用 HandlerThread 的时候,要调用它的 quit() 方法或者 quiteSafely() 方法。
栏 目:Android代码
下一篇:没有了
本文标题:Android HandlerThread案例详解
本文地址:http://www.codeinn.net/misctech/205068.html