安卓app子进程保活方法

安卓或linux的机制是某个进程被杀死之后,它所在的进程组的所有进程都会被杀掉,但有时候客户需要保活它的子进程,按常规的流程无法实现,下面是一种思路方案:
1.当我们点recent键删除app的时候,走下面的流程:

frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
        removeStack->        
     removeTaskByIdLocked  - >
     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
            boolean removeFromRecents) {
        if (removeFromRecents) {   //判断从reecnt移除
            mRecentTasks.remove(tr);
            tr.removedFromRecents();
        }
        ComponentName component = tr.getBaseIntent().getComponent();
        Log.i("fan","component name ="+component);
    /*    if(component.getPackageName().contains("msetpStudentSuite")){
            Log.i("fan","not need kill master process");
            return;
        }*/
        if (component == null) {
            Slog.w(TAG, "No component for base intent of task: " + tr);
            return;
        }

        // Find any running services associated with this app and stop if needed.
        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));

        if (!killProcess) {
            return;
        }

        // Determine if the process(es) for this task should be killed.
        final String pkg = component.getPackageName();
        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
        for (int i = 0; i < pmap.size(); i++) {

            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
            for (int j = 0; j < uids.size(); j++) {
                ProcessRecord proc = uids.valueAt(j);
                if (proc.userId != tr.userId) {
                    // Don't kill process for a different user.
                    continue;
                }
                if (proc == mHomeProcess) {
                    // Don't kill the home process along with tasks from the same package.
                    continue;
                }
                if (!proc.pkgList.containsKey(pkg)) {
                    // Don't kill process that is not associated with this task.
                    continue;
                }

                for (int k = 0; k < proc.activities.size(); k++) {
                    TaskRecord otherTask = proc.activities.get(k).task;
                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
                        // Don't kill process(es) that has an activity in a different task that is
                        // also in recents.
                        return;
                    }
                }

                if (proc.foregroundServices) {
                    // Don't kill process(es) with foreground service.
                    return;
                }
                if(component.getPackageName().contains("msetpStudentSuite")){  //这里根据包名获取进程的pid,保存到全局变量
                
                            Log.i("fan","process pid is"+proc.pid);
                            specialpid = proc.pid;
                }

                // Add process to kill list.
                procsToKill.add(proc);
            }
        }

        // Kill the running processes.
        for (int i = 0; i < procsToKill.size(); i++) {
            ProcessRecord pr = procsToKill.get(i);
            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
                    && pr.curReceiver == null) {
                pr.kill("remove task", true);     //这里开始真正移除要删除的app进程
            } else {
                // We delay killing processes that are not in the background or running a receiver.
                pr.waitingToKill = "remove task";
            }
        }

        
    }
frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
    void kill(String reason, boolean noisy) {
        if (!killedByAm) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill");
            if (noisy) {
                Slog.i(TAG, "Killing " + toShortString() + " (adj " + setAdj + "): " + reason);
            }
            EventLog.writeEvent(EventLogTags.AM_KILL, userId, pid, processName, setAdj, reason);
            Process.killProcessQuiet(pid);
            ActivityManagerService.killProcessGroup(uid, pid);  //通过这个来杀死进程组所有的进程,子进程
            if (!persistent) {
                killed = true;
                killedByAm = true;
            }
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

最后就到了这里
\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
    static void killProcessGroup(int uid, int pid) {
        Log.d("fan","killProcessGroup");
        Log.d("fan",Log.getStackTraceString(new Throwable()));  
        if(specialpid==pid){           //根据前面的id退出要杀的子进程
            Log.i("fan","find special pid is"+pid);
            return;
        }
        if (sKillHandler != null) {
            sKillHandler.sendMessage(
                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
        } else {
            Slog.w(TAG, "Asked to kill process group before system bringup!");
            Process.killProcessGroup(uid, pid);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Android 9.0引入了一种新的应用保活机制,即app进程保活白名单。这个白名单允许应用在后台保持运行状态,以便能够实时接收并处理重要的任务或事件。通过将应用添加到白名单中,可以确保应用不会过早地被系统终止,从而提高了应用的用户体验和功能性。 要将应用添加到Android 9.0的app进程保活白名单中,需要进行以下步骤: 1. 获取系统唤醒锁:应用需要获取系统唤醒锁以防止系统在特定时间内休眠。可以使用PowerManager类的newWakeLock方法来获取唤醒锁,并在不需要时及时释放锁。 2. 启用前台服务:可以将应用设置为前台服务状态,以使其在后台运行时以高优先级运行,并在通知栏中显示一个持续可见的通知。这样,即使应用在后台运行,用户仍然可以清楚地知道应用正在运行。 3. 注册广播接收器:可以注册一些系统广播的接收器,以确保应用在系统事件发生时得到通知并可以及时做出响应。比如注册ACTION_SCREEN_ON广播接收器,以在设备解锁时触发相应的操作。 4. 利用JobScheduler:JobScheduler是Android系统提供的一个调度框架,可以用于安排长期运行的任务,以便应用可以在后台执行这些任务。可以使用JobScheduler来进行任务的调度和管理,以减少应用在后台被系统终止的风险。 需要注意的是,虽然添加到app进程保活白名单可以保持应用在后台的运行状态,但为了避免对系统资源的滥用,应避免长时间运行或频繁使用这些保活方法。合理使用这些保活机制,可以提升应用的性能和用户体验,但也要确保不会对设备的电池寿命和性能造成过多的损失。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术求索者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值