Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
handler 原理_Thread是什么,希望能够帮助你!!!。
要想在非ui线程中使用handler,我们首先想到的是那三大步,Looper.prepare(),创建 handler,Looper.loop(),必要时还要quit一下,这种方法虽合情合理,但总让人感觉丑陋且繁琐,这时候HandlerThread就应运而生了。
IntentService为我们完美展示了HandlerThread的使用方式:
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper); } @Override public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } } //创建HandlerThread并开启 HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); //创建handler并传入HandlerThread维护的Looper mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); //发送消息 Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); //及时销毁 public void onDestroy() {
mServiceLooper.quit(); }
由于HandlerThread源码很简单,所以直接贴出附注释:
public class HandlerThread extends Thread {
int mPriority; int mTid = -1; Looper mLooper; private @Nullable Handler mHandler; //构造方法1 //设置线程名称,并为线程设置默认优先级 public HandlerThread(String name) {
super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } //构造方法2 //设置线程名称,设置优先级 public HandlerThread(String name, int priority) {
super(name); mPriority = priority; } //这里主要做一些消息循环前的初始化工作 protected void onLooperPrepared() {
} @Override public void run() {
//获取当前线程id mTid = Process.myTid(); //创建Looper Looper.prepare(); //使用锁和notifyAll保证getLooper()一定能获取到Looper对象 synchronized (this) {
mLooper = Looper.myLooper(); notifyAll(); } //设置线程优先级 Process.setThreadPriority(mPriority); //准备工作 onLooperPrepared(); //开启循环 Looper.loop(); //释放线程id mTid = -1; } public Looper getLooper() {
if (!isAlive()) {
return null; } // If the thread has been started, wait until the looper has been created. //与之前获取Looper相呼应 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; } //停止消息循环,非线程安全 public boolean quit() {
Looper looper = getLooper(); if (looper != null) {
looper.quit(); return true; } return false; } //停止消息循环,线程安全 API Level 18 public boolean quitSafely() {
Looper looper = getLooper(); if (looper != null) {
looper.quitSafely(); return true; } return false; } /** * Returns the identifier of this thread. See Process.myTid(). */ public int getThreadId() {
return mTid; } }
可以看到,HandlerThread内部也是由handler和Thread封装而成,我们不仅要学习其原理,还要学习它封装的思想,上面源码中getLooper()和run()是异步进行,为了防止获取到的looper为空,使用了wait()进行等待,等looper.myLooper执行结束后再将其唤醒,从而保证在线程存活的情况下一定能getLooper()。
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章