当前位置: 首页 > news >正文

上海 网站平台开发seo推广培训班

上海 网站平台开发,seo推广培训班,个人备案的网站内容,百度糯米网站怎么做Android HandlerThread、Looper、MessageQueue 源码分析 简介 在 Android 开发中,大家应该对 HandlerThread 有一定了解。顾名思义,HandlerThread 是 Thread 的一个子类。与普通的 Thread 不同,Thread 通常一次只能执行一个后台任务&#x…

Android HandlerThread、Looper、MessageQueue 源码分析

简介

Android 开发中,大家应该对 HandlerThread 有一定了解。顾名思义,HandlerThreadThread 的一个子类。与普通的 Thread 不同,Thread 通常一次只能执行一个后台任务,如果需要执行多个任务,就必须创建多个线程,这样容易导致资源管理复杂,甚至可能出现内存泄漏等问题。而 HandlerThread 有一个显著的特点,它能够串行地执行多个任务。每个任务通过消息的形式排队执行,线程池中的任务按顺序依次处理,无需手动管理线程的生命周期或调度过程。我们只需通过 Handler 将任务发送到 HandlerThread 中,它会自动按顺序执行,极大简化了开发过程。使用 HandlerThread 的最大优势是:它是单线程的,因此不需要担心线程安全问题。实际上,Android 源码中也有许多地方使用了 HandlerThread,它在设计思想上值得我们学习和借鉴。接下来,我们将通过源码进一步了解它的实现原理。

源码分析

HandlerThread内部持有一个Looper,Looper中持有一个消息队列MessageQueue

Looper

在了解HandlerThread前,我们有必要先认识一下Looper,Looper 是一个负责管理消息队列(MessageQueue)并循环处理其中消息的类。简单来说,Looper 通过不断地从消息队列中取出消息并处理它们,来实现线程的消息处理机制。每个线程都有自己的消息队列和 Looper,通过 Looper,线程能够不断地处理任务直到任务队列为空。接下来我们会涉及到它以下几个核心接口。

  • prepare() 是一个静态方法,用来构建一个Looper对象,quitAllowed表示这个Looper是否支持退出,默认是支持,像Android 主线程的Looper是不支持退出的
    public static void prepare() {prepare(true);}
  • loopOnce 静态方法,顾名思义,循环一次,它的作用是从当前消息队列MessageQueue中取一条符合条件的消息进行分发操作
private static boolean loopOnce(final Looper me,final long ident, final int thresholdOverride) {Message msg = me.mQueue.next(); // 取一条消息if (msg == null) {//正常没消息,队列会堵塞,不会返回null,所以这里是null肯定是已经要结束了,这里返回false 退出looperreturn false;}//分发消息代码逻辑省略}
  • loop() 静态方法,启动循环,在循环中不断调用loopOnce来处理消息
//关键代码public static void loop() {final Looper me = myLooper();
//...for (;;) {if (!loopOnce(me, ident, thresholdOverride)) {//返回false 意味着循环结束return;}}}
  • quit()quitSafely() 退出looper,前者是立即退出,后者是处理完当前队列中所有消息后退出,最终是调用消息队列MessageQueue对应的退出方法
    public void quit() {mQueue.quit(false);
}public void quitSafely() {mQueue.quit(true);
}

HandlerThread

  • 既然它是一个线程,那可以先从run方法入手:
@Overridepublic void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;}

可以看出,线程跑起来后,先初始化了一个Looper,然后启动死循环,HandlerThread在这里充当的作用是在子线程中开启死循环接受和分发消息
这里有个地方比较有意思,在mLooper = Looper.myLooper();后面,它调用了notifyAll(),它起到了什么作用呢?

  • getLooper(),我们应该知道要把任务提交给HandlerThread执行,需要借助Handler,但是Handler的构造参数是需要传入一个Looper对象,所以,这里对外公开了获取Looper的接口
public Looper getLooper() {if (!isAlive()) {return null;}boolean wasInterrupted = false;// If the thread has been started, wait until the looper has been created.synchronized (this) {while (isAlive() && mLooper == null) {try {wait();} catch (InterruptedException e) {wasInterrupted = true;}}}/** We may need to restore the thread's interrupted flag, because it may* have been cleared above since we eat InterruptedExceptions*/if (wasInterrupted) {Thread.currentThread().interrupt();}return mLooper;}

这里是直接返回了在run中初始化的mLooper,但是呢,在非当前线程获取mLooper对象,就会引发线程安全问题,可能mLooper还没被初始化就调用了getLooper(),这样就有可能返回一个空的数据了,所以官方在这里做了while循环,并且使用了wait()堵塞,等待上面run初始化完成后再notifyAll()这里

  • getThreadHandler() 就是公开给外面向当前HandlerThread插入消息的接口,内部维护着一个Handler对象
    @NonNullpublic Handler getThreadHandler() {if (mHandler == null) {mHandler = new Handler(getLooper());}return mHandler;}
  • quit()quitSafely() 同样,HandlerThread也有退出的方法,其实现也是调用looper对应的函数退出

MessageQueue

由于关于消息分发逻辑在其他地方讲过,这里只要分析退出队列的逻辑。
它实现了退出和安全退出的方法,这两个操作有什么区别呢,请看源码

  • next() looper每调用一次loopOnce,内部就会调用messageQueue获取一条消息
Message next() {//只放关键代码for (; ; ) {//堵塞,等待消息或者时机合适或主动唤醒nativePollOnce(ptr, nextPollTimeoutMillis);//...//符合分发条件的 返回这条消息给looperif (msg != null) {//...return msg;} else {// No more messages.nextPollTimeoutMillis = -1;}//...//退出状态 则释放队列,结束循环if (mQuitting) {dispose();return null;}}
}
  • quit()实际逻辑由下面两个removeAllFutureMessagesLocked和removeAllMessagesLocked函数执行
void quit(boolean safe) {if (!mQuitAllowed) {throw new IllegalStateException("Main thread not allowed to quit.");}synchronized (this) {if (mQuitting) {//如果已经给队列设置了退出信号,下面的逻辑就不用走了return;}mQuitting = true;//标记当前队列处于退出状态,此时不再接受新的消息if (safe) {//安全退出removeAllFutureMessagesLocked();} else {//立即退出removeAllMessagesLocked();}//把队列的消息标记完成后,唤醒上面next的堵塞位置nativePollOnce,执行剩下的退出逻辑nativeWake(mPtr);}
}
//移除所有消息
private void removeAllMessagesLocked() {//mMessages 在这里是队列的头Message p = mMessages;while (p != null) {//从头开始,把所有消息标记为回收状态Message n = p.next;p.recycleUnchecked();p = n;}mMessages = null;//队头消息置空,next()执行时会判断这个,为空直接退出队列
}//移除所有未来消息,退出这一瞬间之前提交的消息保留继续执行
private void removeAllFutureMessagesLocked() {final long now = SystemClock.uptimeMillis();Message p = mMessages;if (p != null) {if (p.when > now) {//队头的时间比当前新,说明全是后面新加的,全部回收掉removeAllMessagesLocked();} else {//以下为从消息队列中找到退出那一瞬间时间一样的分割点,把分割点前的消息与队列断开链接Message n;for (;;) {n = p.next;if (n == null) {return;}if (n.when > now) {break;}p = n;}p.next = null;//断开链接,这里把队列从分割点切断do {p = n;n = p.next;p.recycleUnchecked();//把所有未来消息标记为回收状态} while (n != null);}}
}

从上面可以看出,安全退出时,队列会把所有未来消息移除掉,并且不再接受新的消息,队列中剩下的消息会继续被looper取,一直到取完为止,然后结束队列退出循环,而普通退出就会把队列中所有消息移除,然后紧接着结束队列退出循环

quit和quitSafely 应用场景有哪些呢

;//把所有未来消息标记为回收状态
} while (n != null);
}
}
}


从上面可以看出,安全退出时,队列会把所有未来消息移除掉,并且不再接受新的消息,队列中剩下的消息会继续被looper取,一直到取完为止,然后结束队列退出循环,而普通退出就会把队列中所有消息移除,然后紧接着结束队列退出循环### quit和quitSafely 应用场景有哪些呢
举一个简单的例子,在Android 使用Room操作数据库,由于操作数据库需要在子线程,所以,我们可以构造一个`HandlerThread`,专门处理操作数据库的任务,如果操作过程非常耗时,然后又要关闭数据库,

文章转载自:
http://naloxone.c7630.cn
http://corymbose.c7630.cn
http://mixotrophic.c7630.cn
http://cystitis.c7630.cn
http://plagiarise.c7630.cn
http://whittret.c7630.cn
http://auriform.c7630.cn
http://changepocket.c7630.cn
http://fyn.c7630.cn
http://illy.c7630.cn
http://cckw.c7630.cn
http://rheotropism.c7630.cn
http://impercipience.c7630.cn
http://levant.c7630.cn
http://radiogenetics.c7630.cn
http://noncommittal.c7630.cn
http://croup.c7630.cn
http://irgb.c7630.cn
http://dormition.c7630.cn
http://neurosecretion.c7630.cn
http://fume.c7630.cn
http://rapeseed.c7630.cn
http://semitics.c7630.cn
http://defogger.c7630.cn
http://sanitationman.c7630.cn
http://lavvy.c7630.cn
http://period.c7630.cn
http://orangism.c7630.cn
http://float.c7630.cn
http://fungoid.c7630.cn
http://prioral.c7630.cn
http://capillaceous.c7630.cn
http://sanguinivorous.c7630.cn
http://lunchhook.c7630.cn
http://dishonesty.c7630.cn
http://pannier.c7630.cn
http://tinplate.c7630.cn
http://martensitic.c7630.cn
http://miter.c7630.cn
http://thyrsus.c7630.cn
http://turgescent.c7630.cn
http://mitbestimmung.c7630.cn
http://snakehead.c7630.cn
http://thousandth.c7630.cn
http://romaic.c7630.cn
http://ultrafiche.c7630.cn
http://monoplane.c7630.cn
http://doloroso.c7630.cn
http://famacide.c7630.cn
http://unrhymed.c7630.cn
http://cataplastic.c7630.cn
http://nutant.c7630.cn
http://postillion.c7630.cn
http://happenings.c7630.cn
http://yard.c7630.cn
http://recklessness.c7630.cn
http://oestrum.c7630.cn
http://laqueus.c7630.cn
http://extravagance.c7630.cn
http://mainliner.c7630.cn
http://mater.c7630.cn
http://unadvanced.c7630.cn
http://virogenetic.c7630.cn
http://superzealot.c7630.cn
http://dander.c7630.cn
http://grassfinch.c7630.cn
http://bewilder.c7630.cn
http://pacifiable.c7630.cn
http://antares.c7630.cn
http://pud.c7630.cn
http://tuvaluan.c7630.cn
http://polyspermy.c7630.cn
http://impoverish.c7630.cn
http://catabolite.c7630.cn
http://pleb.c7630.cn
http://ciq.c7630.cn
http://sternness.c7630.cn
http://smocking.c7630.cn
http://offlet.c7630.cn
http://twelfth.c7630.cn
http://culpa.c7630.cn
http://vestalia.c7630.cn
http://mercantilism.c7630.cn
http://cryotron.c7630.cn
http://unscrupulousness.c7630.cn
http://acinaciform.c7630.cn
http://allograph.c7630.cn
http://masticatory.c7630.cn
http://cloke.c7630.cn
http://particularity.c7630.cn
http://retool.c7630.cn
http://apercu.c7630.cn
http://traitoress.c7630.cn
http://frequency.c7630.cn
http://quantitate.c7630.cn
http://rubellite.c7630.cn
http://riverway.c7630.cn
http://maror.c7630.cn
http://rhynchocephalian.c7630.cn
http://enamelling.c7630.cn
http://www.zhongyajixie.com/news/84651.html

相关文章:

  • 昆明中小企业网站建设中国搜索引擎
  • 网站虚拟服务器软文小故事200字
  • 苏州做网站的专业公司哪家好seo 优化技术难度大吗
  • wordpress 编辑软件如何进行网站性能优化
  • 企业网站怎么做才能留住客户如何免费注册一个网站
  • 在相亲网站做红娘2021年网络营销案例
  • 如何做好网站宣传小吃培训2000元学6项
  • 柳州网站虚拟主机销售价格一份完整的营销策划方案
  • 门户网站开发视频福州seo扣费
  • 北京企业官网网站建设哪家好seo标题优化裤子关键词
  • 常州公司网站建设百度手机助手
  • 网站设计字体大小规范镇江百度推广
  • 菠菜源码怎么做网站seo作弊
  • 腾讯企点下载官网seo chinaz
  • 深圳专业建站多少钱如何推广小程序
  • 珠海响应式网站建设价格推广app拉人头赚钱
  • 广州手机网站建设价格哪里有网页设计公司
  • 二手车网站开发PPT百度站长统计工具
  • 做网站要费用多少企业宣传片视频
  • 和平精英免费开科技软件网站关键词排名手机优化软件
  • 滨州公司网站建设网页设计与制作软件
  • 盐城做网站的公司地址广州搜索排名优化
  • 网站数据库是谁提供今天济南刚刚发生的新闻
  • 做的好的音乐网站网络营销seo是什么意思
  • 端午节网站建设品牌推广活动策划方案
  • wordpress more标签使用教程优化大师有必要安装吗
  • 织梦搭建本地网站手机seo快速排名
  • 做网站需要看那几点一键优化免费下载
  • 做国外搞笑网站哈尔滨seo优化公司
  • 跳蛋塞逼做多的视频网站百度top风云榜