searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

谈谈Android Persistent属性

2023-05-04 01:05:52
259
0

1. 引言

在应用AndroidManifest中添加 android:persistent="true" 关键字,并把应用APK预置到system/app目录下,可以给应用实现开机自启动和保活效果。我们带着以下两个疑问去看看是怎么实现的:

  1. 开机自启动 how?
  2. adb shell 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.applicationdemo​

查看进程的oom_adj值是-800,优先级非常高,可以看出带persistent的进程很难被系统杀死。

xxx64:/ # cat proc/3329/oom_score_adj                                                                                                                                    
-800
xxx64:/ # 

ActivityManagerService.javastartProcessLocked启进程的方法中打调用栈如下:

    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 QXL
            if(null != app && app.processName != null && app.processName.equals("com.example.applicationdemo")) {
                android.util.Log.d("qxl","ams startProcessLocked stack:"
                            + android.util.Log.getStackTraceString(new Throwable()));
            }

重启设备抓开机Log,结果如下:

开机自启动是在ActivityManagerService服务SystemReady后中调用startPersistentApps方法拉起所有persistent应用。

3. kill -9 杀进程后会自动重启

虽然persistent特性的应用进程oom_adj-800很难被系统杀掉,但不排除其他因素导致应用进程被杀,比如通过adb shell kill -9 xxx命令即可杀掉某个进程。作用于上面的persistent应用试试:

adb shell kill -9 3329

此时打印调用栈信息如下:

由此可以看到persistent进程被杀后,触发了进程启动时和AMS之间的Binder墓碑机制走到cleanUpApplicationRecordLocked方法,针对persistent应用设置restart标记后执行startProcessLock重新拉起进程。

Binder墓碑机制如下图所示:

小结

搞清楚persistent实现应用保活的过程后,我们可以基于这个机制实现一些三方应用的保活个性化需求。在这个基础上应用只需要重写ApplicationonCreate方法做进程拉起后的业务逻辑即可。

 

0条评论
0 / 1000
hi_long
15文章数
0粉丝数
hi_long
15 文章 | 0 粉丝
hi_long
15文章数
0粉丝数
hi_long
15 文章 | 0 粉丝
原创

谈谈Android Persistent属性

2023-05-04 01:05:52
259
0

1. 引言

在应用AndroidManifest中添加 android:persistent="true" 关键字,并把应用APK预置到system/app目录下,可以给应用实现开机自启动和保活效果。我们带着以下两个疑问去看看是怎么实现的:

  1. 开机自启动 how?
  2. adb shell 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.applicationdemo​

查看进程的oom_adj值是-800,优先级非常高,可以看出带persistent的进程很难被系统杀死。

xxx64:/ # cat proc/3329/oom_score_adj                                                                                                                                    
-800
xxx64:/ # 

ActivityManagerService.javastartProcessLocked启进程的方法中打调用栈如下:

    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 QXL
            if(null != app && app.processName != null && app.processName.equals("com.example.applicationdemo")) {
                android.util.Log.d("qxl","ams startProcessLocked stack:"
                            + android.util.Log.getStackTraceString(new Throwable()));
            }

重启设备抓开机Log,结果如下:

开机自启动是在ActivityManagerService服务SystemReady后中调用startPersistentApps方法拉起所有persistent应用。

3. kill -9 杀进程后会自动重启

虽然persistent特性的应用进程oom_adj-800很难被系统杀掉,但不排除其他因素导致应用进程被杀,比如通过adb shell kill -9 xxx命令即可杀掉某个进程。作用于上面的persistent应用试试:

adb shell kill -9 3329

此时打印调用栈信息如下:

由此可以看到persistent进程被杀后,触发了进程启动时和AMS之间的Binder墓碑机制走到cleanUpApplicationRecordLocked方法,针对persistent应用设置restart标记后执行startProcessLock重新拉起进程。

Binder墓碑机制如下图所示:

小结

搞清楚persistent实现应用保活的过程后,我们可以基于这个机制实现一些三方应用的保活个性化需求。在这个基础上应用只需要重写ApplicationonCreate方法做进程拉起后的业务逻辑即可。

 

文章来自个人专栏
Android
15 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0