谈谈Persistent属性
文章目錄
-
- 1. 背景
- 2. 開機自啟動流程
- 3. adb kill -9 殺進程后會自動重啟
- 4. 小結
1. 背景
在應用AndroidManifest文件下添加 android:persistent=“true” 關鍵字,并把Apk預置到system/app目錄下,可以給應用實現開機自啟動和保活效果。
從以下兩個疑問去找答案:
- 開機自啟動 how?
- adb kill -9 殺進程后會自動重啟 how?
2. 開機自啟動流程
開機后通過adb shell ps -A | grep 包名查看進程號,確實起了進程。
? Desktop psa | grep demo
u0_a61 3329 3329 1753 3600572 83104 ep_poll 7b2c9a4ff34a S e.ecloudapidemo
查看進程的oom_adj值是-800,優先級非常高,可以看出帶persistent的進程很難被系統殺死。
xxx64:/ # cat proc/3329/oom_score_adj
-800
xxx64:/ #
在ActivityManagerService.java的startProcessLocked方法打調用棧如下:
private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {app.pendingStart = true;app.killedByAm = false;app.removed = false;app.killed = false;final long startSeq = app.startSeq = ++mProcStartSeqCounter;app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);if (mConstants.FLAG_PROCESS_START_ASYNC) {if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,"Posting procStart msg for " + app.toShortString());//Add by QXLif(null != app && app.processName != null && app.processName.equals("com.example.ecloudapidemo")) {android.util.Log.d("qxl","ams startProcessLocked stack:"+ android.util.Log.getStackTraceString(new Throwable()));}
重啟設備抓開機Log,結果如下:
02-07 01:09:41.247 1941 1956 D qxl : ams startProcessLocked stack:java.lang.Throwable
02-07 01:09:41.247 1941 1956 D qxl : at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4486)
02-07 01:09:41.247 1941 1956 D qxl : at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4451)
02-07 01:09:41.247 1941 1956 D qxl : at com.android.server.am.ActivityManagerService.addAppLocked(ActivityManagerService.java:13289)
02-07 01:09:41.247 1941 1956 D qxl : at com.android.server.am.ActivityManagerService.addAppLocked(ActivityManagerService.java:13253)
02-07 01:09:41.247 1941 1956 D qxl : at com.android.server.am.ActivityManagerService.startPersistentApps(ActivityManagerService.java:13011)
02-07 01:09:41.247 1941 1956 D qxl : at com.android.server.am.UserController$Injector.startPersistentApps(UserController.java:2195)
02-07 01:09:41.247 1941 1956 D qxl : at com.android.server.am.UserController.finishUserUnlocked(UserController.java:449)
02-07 01:09:41.247 1941 1956 D qxl : at com.android.server.am.UserController.handleMessage(UserController.java:1999)
02-07 01:09:41.247 1941 1956 D qxl : at android.os.Handler.dispatchMessage(Handler.java:102)
02-07 01:09:41.247 1941 1956 D qxl : at android.os.Looper.loop(Looper.java:193)
02-07 01:09:41.247 1941 1956 D qxl : at android.os.HandlerThread.run(HandlerThread.java:65)
02-07 01:09:41.247 1941 1956 D qxl : at com.android.server.ServiceThread.run(ServiceThread.java:44)
開機自啟動的流程就比較清楚了。
3. adb kill -9 殺進程后會自動重啟
雖然persistent特性的應用進程oom_adj是-800很難被系統殺掉,但不排除其他因素導致應用進程被殺,比如我們通過命令adb shell kill -9 xxx即可殺掉某個進程。
作用于上面的persistent應用試試:
adb shell kill -9 3329
此時打印調用棧信息如下:
02-07 01:10:37.374 1941 2066 D qxl : ams startProcessLocked stack:java.lang.Throwable
02-07 01:10:37.374 1941 2066 D qxl : at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4486)
02-07 01:10:37.374 1941 2066 D qxl : at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4451)
02-07 01:10:37.374 1941 2066 D qxl : at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4266)
02-07 01:10:37.374 1941 2066 D qxl : at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4260)
02-07 01:10:37.374 1941 2066 D qxl : at com.android.server.am.ActivityManagerService.cleanUpApplicationRecordLocked(ActivityManagerService.java:20377)
02-07 01:10:37.374 1941 2066 D qxl : at com.android.server.am.ActivityManagerService.handleAppDiedLocked(ActivityManagerService.java:5968)
02-07 01:10:37.374 1941 2066 D qxl : at com.android.server.am.ActivityManagerService.appDiedLocked(ActivityManagerService.java:6162)
02-07 01:10:37.374 1941 2066 D qxl : at com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied(ActivityManagerService.java:1897)
02-07 01:10:37.374 1941 2066 D qxl : at android.os.BinderProxy.sendDeathNotice(Binder.java:1193)
由此可以看到persistent進程被殺后,觸發了進程啟動時和AMS之間的binder墓碑機制走到cleanUpApplicationRecordLocked方法,針對persistent應用AMS會重新拉起新的進程。
應用進程啟動后如何和AMS綁上這樣的關系?可以參考其他人畫的流程圖:
4. 小結
大概搞清楚persistent的實現后,我們可以基于這個機制做保活和自啟名單的定制需求了。Application這邊可以利用重寫Application的onCreate方法做進程拉起后的業務邏輯。
總結
以上是生活随笔為你收集整理的谈谈Persistent属性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu下aMule设置
- 下一篇: 在扩展Spock时输出给定值