handler 原理_Thread是什么

(4) 2024-08-07 10:12

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()。

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

上一篇

已是最后文章

下一篇

已是最新文章

发表回复