###1. android persistent app

在android 系统中, 有一种永久性的app, 它们会在开机时自启动, 并且在出现异常时, 能够自动重启, 永久性的应用, 是通过在 AndroidManifest.xml 文件中声明 android:persistent=”true” 来实现的

###2. persistent app的实现

在PackageManagerService中有一个hash表, 用于记录所有app的信息

final HashMap<String, PackageParser.Package> mPackages = new HashMap<String, PackageParser.Package>();

其中 PackageParser.Package.applicationInfo 成员保存了app的相关信息, 当app被声明为persistent app时(android:persistent=”true”), 其对应的 PackageParser.Package.applicationInfo.flag 成员的 FLAG_PERSISTENT 位会被置1, 标记其为persistent app

PackageManagerService.getPersistentApplications()可用于获取所有的persistent app的 ApplicationInfo

####2.1 persistent app的自启动

在ActivityManagerService.systemReady()中, 会通过 PackageManagerService 获取所有的persistent app并且启动它们

public void systemReady(final Runnable goingCallback) {
	......
	synchronized (this) {
        		if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            		try {
                		List apps = AppGlobals.getPackageManager().getPersistentApplications(STOCK_PM_FLAGS);
                		if (apps != null) {
                    			int N = apps.size();
                    			int i;
                    			for (i=0; i<N; i++) {
                        			ApplicationInfo info = (ApplicationInfo)apps.get(i);
                        			if (info != null && !info.packageName.equals("android")) {
                            				addAppLocked(info, false, null /* ABI override */);
                        			}
                    			}
                		}
            		} catch (RemoteException ex) {
                		// pm is in same process, this will never happen.
            		}
        	}
	......
}

对所有包名不为“android”的persistent app执行 addAppLocked(), addAppLocked()中会添加一个与App进程对应的ProcessRecord节点(不会重复添加), 然后检查到若该app进程是否启动,若未启动,则会调用startProcessLocked()启动该app进程

启动进程的过程是异步的, 一旦目标进程启动完毕后, 会走到ActivityManagerService.attachApplicationLocked(), 其中会删除对应的ProcessRecord节点

####2.2 persistent app的自动重启

每个ActivityThread中会有一个专门和AMS通信的binder实体——final ApplicationThread mAppThread, 在启动app进程完成后, ActivityManagerService.attachApplicationLocked()中会为该ApplicationThread注册一个死亡监听

try {
        AppDeathRecipient adr = new AppDeathRecipient(
                app, pid, thread);
        thread.asBinder().linkToDeath(adr, 0);
        app.deathRecipient = adr;
    } catch (RemoteException e) {
        app.resetPackageList(mProcessStats);
        startProcessLocked(app, "link fail", processName);
        return false;
    }

当监听的 AtivityThread 死亡后, AppDeathRecipient.binderDied()会被回调, 最终会重启

AppDeathRecipient.binderDied()
	appDiedLocked()
		handleAppDiedLocked()

private final boolean cleanUpApplicationRecordLocked()	{
	......
	} else if (!app.removed) {
        		// This app is persistent, so we need to keep its record around.
        		// If it is not already on the pending app list, add it there
        		// and start a new process for it.
        		if (mPersistentStartingProcesses.indexOf(app) < 0) {
            			mPersistentStartingProcesses.add(app);
            			restart = true;
        		}
    		}
	......
	if (restart && !app.isolated) {
        		// We have components that still need to be running in the
        		// process, so re-launch it.
        		if (index < 0) {
            			ProcessList.remove(app.pid);
        		}
        		mProcessNames.put(app.processName, app.uid, app);
        		startProcessLocked(app, "restart", app.processName);
        		return true;
	......
}