编程

当前位置:澳门新莆京娱乐官网 > 编程 > 主线程中的Looper

主线程中的Looper

来源:http://www.drgigabytes.com 作者:澳门新莆京娱乐官网 时间:2020-03-23 05:37

正如作者辈所知,在android中纵然主线程中实行耗费时间操作会引发AN奥迪Q3(Application Not Responding)格外。

招致ANSportage的原由平常有三种:

  1. 时下的风云还未有机缘得随地理(即主线程正在管理前八个风云,未有立时的完结也许looper被某种原因拥塞住了)
  2. 日前的事件正在管理,但从不应声到位

为了幸免AN翼虎万分,android使用了Handler消息处理机制。让耗费时间操作在子线程运营。

所以产生了三个主题素材,主线程中的Looper.loop(卡塔尔一向Infiniti循环检查测试音讯队列中是或不是有新新闻为何不会导致ANKoleos?

本人面试网易的时候就被问到了T_T

ActivityThread.java 是主线程入口的类,这里你能够观察写Java程序中管见所及的main方法,而main方法正是整个Java程序的入口。

ActivityThread源码

 public static final void main(String[] args) { ... //创建Looper和MessageQueue Looper.prepareMainLooper(); ... //轮询器开始轮询 Looper.loop(); ... }

Looper.loop()方法

 while  { //取出消息队列的消息,可能会阻塞 Message msg = queue.next(); // might block ... //解析消息,分发消息 msg.target.dispatchMessage; ... }

万目睽睽的,若是main方法中绝非looper进行巡回,那么主线程一运维完毕就能够退出。那还玩个蛋啊!

小结:ActivityThread的main方法首要便是做消息循环,一旦退出新闻循环,那么您的接纳也就淡出了。

小编们知晓了消息循环的要求性,那怎么这几个死循环不会变成ANCRUISER万分呢?

因为Android 的是由事件驱动的,looper.loop(卡塔尔(قطر‎不断地接到事件、处管事人件,每二个点击触摸恐怕说Activity的生命周期都以运作在 Looper.loop()的支配之下,假使它甘休了,应用也就终止了。只好是某叁个信息或然说对消息的拍卖窒碍了 Looper.loop(卡塔尔国,实际不是 Looper.loop(卡塔尔(قطر‎ 阻塞它。

也就说咱俩的代码其实正是在那些轮回之中去执行的,当然不会卡住了。

handleMessage方法有个别源码

 public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString); switch  { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity; Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case RELAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); ActivityClientRecord r = (ActivityClientRecord) msg.obj; handleRelaunchActivity; Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case PAUSE_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); handlePauseActivity msg.obj, false, (msg.arg1 & 1) != 0, msg.arg2, (msg.arg1 & 2) != 0); maybeSnapshot(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case PAUSE_ACTIVITY_FINISHING: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); handlePauseActivity msg.obj, true, (msg.arg1 & 1) != 0, msg.arg2, (msg.arg1 & 1) != 0); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; ........... } }

可以知道Activity的生命周期都是依据主线程的Looper.loop,当接到不一致Message时则选择相应措施。

设若有个别音讯管理时间过长,举例你在onCreate(卡塔尔国,onResume(State of Qatar里面管理耗时操作,那么下一回的新闻譬喻客商的点击事件不可能处理了,整个循环就能够生出卡顿,时间一长就成了ANKuga。

让大家再看一遍形成ANPAJERO的缘由,你可能就懂了。

诱致AN讴歌ZDX的由来平常有二种:

  1. 时下的风波还未机缘获取管理(即主线程正在处理前一个平地风波,未有及时的完毕或许looper被某种原因拥塞住了)
  2. 日前的事件正在管理,但尚无立时到位

并且主线程Looper从新闻队列读取新闻,当读完全数消息时,主线程拥塞。子线程往新闻队列发送新闻,何况往管道文件写多少,主线程即被升迁,从管道文件读取数据,主线程被唤醒只是为了读取音讯,当音讯读取达成,再一次睡眠。因而loop的巡回并不会对CPU品质有过多的费用。

总括:Looer.loop(卡塔尔(قطر‎方法可能会唤起主线程的隔离,但假使它的音信循环未有被封堵,能直接处管事人件就不会生出ANPRADO卓殊。

参考

本文由澳门新莆京娱乐官网发布于编程,转载请注明出处:主线程中的Looper

关键词:

上一篇:没有了

下一篇:没有了