问题:Android开机之后,很快就去启动应用播放视频,长按power key进入关机,但是有时候关机会花很长时间。

疑点:关机广播发送到接收时间较长;activity stack shutdown(activities finish)花费时间较长。

分析:关机flow主要集中在shutdownThread,加打印trace长按power键,Android关机flow。

背景:原生的shutdown关机分为high level(Android系统)和low level(kernel/driver),这里主要分析high level。

知识点:broadcast的发送和接收;activity进栈和退栈及启动模式的了解。

正常和异常打印时间戳:


一、BroadcastReceiver

  • Broadcast的种类
  1. 并发和有序
  2. 前台和后台
  3. 系统和自定义
  • BroadcastReceiver的注册方式
  1. 静态
  2. 动态
  • Broadcast的发送:
  • Broadcast的接收:
  • BroadcastReceiver注册时序

 原图链接:https://blog.csdn.net/u011733869/article/details/83796225

  • Broadcast发送到接收的时序

 原图链接:https://blog.csdn.net/u011733869/article/details/83834656

 原图链接:https://blog.csdn.net/sinat_29255093/article/details/51817760

  • shutdownBroadcast的时序 --待补

二、Activity

  • activity的启动模式:standard、singleTop、singleTask、singleInstance
  • ActivityStack、TaskStack、ActivityRecord
  1. 理清这三者之间的关系

      原图链接:https://www.jianshu.com/p/94816e52cd77

           原图链接:https://www.jianshu.com/p/94816e52cd77 

dumpsys activity activities的抽取关键info如下:可以看到,

有三个stack,对应三个ActivityStack,StackId 0、1、2

ActivityStackId 2 ->TaskRecord Id 41->ActivityRecord:com.netflix.ninja/.MainActivity

ActivityStackId 0 ->TaskRecord Id 40->ActivityRecord:com.google.android.tvlauncher/.MainActivity

ActivityStackId 1 ->TaskRecord Id 39->ActivityRecord:com.google.com.customer.tv/.TVActivity

Stack #2: type=standard mode=fullscreen..........//此处省略Running activities (most recent first):      TaskRecord{8329e0f #41 A=com.netflix.ninja U=0 StackId=2 sz=1}      Run #0: ActivityRecord{b66c2d7 u0 com.netflix.ninja/.MainActivity t41}mResumedActivity: ActivityRecord{b66c2d7 u0 com.netflix.ninja/.MainActivity t41}Stack #0: type=home mode=fullscreen...........//此处省略Running activities (most recent first):      TaskRecord{8500e9c #40 A=.TvLauncher U=0 StackId=0 sz=1}      Run #0: ActivityRecord{e12b727 u0 com.google.android.tvlauncher/.MainActivity t40}mLastPausedActivity: ActivityRecord{e12b727 u0 com.google.android.tvlauncher/.MainActivity t40}Stack #1: type=standard mode=fullscreen............//此处省略Running activities (most recent first):      TaskRecord{731f0a5 #39 A=com.customer.tv U=0 StackId=1 sz=1}      Run #0: ActivityRecord{7cf3c8e u0 com.customer.tv/.TVActivity t39}mLastPausedActivity: ActivityRecord{7cf3c8e u0 com.customer.tv/.TVActivity t39}ResumedActivity: ActivityRecord{b66c2d7 u0 com.netflix.ninja/.MainActivity t41}mFocusedStack=ActivityStack{c33ec7a stackId=2 type=standard mode=fullscreen visible=true translucent=false, 1 tasks} mLastFocusedStack=ActivityStack{c33ec7a stackId=2 type=standard mode=fullscreen visible=true translucent=false, 1 tasks}  mCurTaskIdForUser={0=41}  mUserStackInFront={}  displayId=0 stacks=3  mHomeStack=ActivityStack{4850c2b stackId=0 type=home mode=fullscreen visible=false translucent=true, 1 tasks}  isHomeRecentsComponent=false  KeyguardController:    mKeyguardShowing=false    mAodShowing=false    mKeyguardGoingAway=false    mOccluded=false    mDismissingKeyguardActivity=null    mDismissalRequested=false    mVisibilityTransactionDepth=0  LockTaskController    mLockTaskModeState=NONE    mLockTaskModeTasks=    mLockTaskPackages (userId:packages)=      u0:[]
  • AMS shutdown耗时分析
  1. trace ams.shutdown源码可以看到分为四个部分做shutdown,打印时间戳,正常与异常log

        

        

三、小结

  1. 开机系统起来会有很多的后台广播:比如开机广播、网络变化广播、Timetick广播等。有些是并发广播,有些是有序广播。开机之后PKMS扫描清单文件里注册的Receiver(静态注册receiver,pkms先扫到的先接收到广播),AMS会将广播发送给相应的receiver处理,比如开机广播,有的要实现app自启动,这个会耗时,如果这个时候关机发送有序的关机广播,那就要等前一个receiver甚至前几个receiver接收处理完之后 才能轮到shutdownThread receiver接收处理关机广播(而且还要考虑priority),这样就会有概率性超时,如果开机之后等几分钟在去关机就不会出现关机广播超时的情况,因为那个时候基本上所有的开机广播都处理完了。
  2. 一方面shutdownThread的Broadcast推迟接收处理,另一方面开机自启动的应用很多,直观地dumpsys activity activities 也可以看到stackID=0,1,2;分别是tvlauncher、Netflix、TvActivity,那ActivityStackSupervisor作为ActivityStack的管理者,shutdown的时候需要分别将对应的stack做shutdown。耗时的部分还有ProcessStats.shutdown,包括后台进程,在shutdown之前都需要写进程状态,进程越多,花费的时候越多。

四、感悟

  1. 四大组件是基础,还是要夯实基础
  2. 学的知识点还是要记下来,多debug、多总结

更多相关文章

  1. Android开机自启动
  2. cordova + ionic前端框架 js和android ios原生(native)交互
  3. 【Android】Android(安卓)监听apk安装替换卸载广播
  4. android系统权限关机重启
  5. android 唤醒屏幕
  6. android 全面讲解BroadCastReceiver
  7. Android初级教程启动定时器详解
  8. 判断应用是安装还是卸载了
  9. Android系统开机启动流程

随机推荐

  1. 自定义Spinner下拉列表
  2. 布局中@null的代码实现方式
  3. [译] Android(安卓)开发最佳实践
  4. Android---把数据保存到数据库中(一)
  5. 【6.21】PreferenceActivity来设置settin
  6. android 热更新之腾讯Bugly 及所遇问题的
  7. Android非常简单的TextView展开和收起,在
  8. Android---线程间通讯
  9. [置顶] 【Android】 给我一个Path,还你一
  10. Android中运行OpenGL工程出错:java.lang.I