以下代碼基于Android9.0
persistent屬性的定義
開(kāi)發(fā)系統(tǒng)應(yīng)用時(shí),有時(shí)我們需要應(yīng)用常駐,被殺死后能夠自動(dòng)重啟家夺,此時(shí)就需要使用到persistent屬性,
下面是關(guān)于該屬性在framework層的定義疤坝,屬性的定義位于
persistent屬性定義在platform/frameworks/base/core/res/res/values/attrs_manifest.xml文件內(nèi):
<!-- 控制應(yīng)用程序是否處于特殊持久模式的標(biāo)志,通常情況下不應(yīng)該被使用,該標(biāo)志位能夠保證應(yīng)用程序一直運(yùn)行 -->
<attr name="persistent" format="boolean" />
persistent屬性的使用
開(kāi)發(fā)系統(tǒng)應(yīng)用時(shí)亲雪,有時(shí)我們需要應(yīng)用常駐勇凭,被殺死后能夠自動(dòng)重啟,此時(shí)我們就要在應(yīng)用的AndroidManifest.xml中設(shè)置
android:persistent="true"
設(shè)置后應(yīng)用就具備了以下兩個(gè)特性:
- 系統(tǒng)啟動(dòng)時(shí)該應(yīng)用也會(huì)啟動(dòng)
- 應(yīng)用被殺死后义辕,系統(tǒng)會(huì)重啟該應(yīng)用
persistent屬性的原理
persistent屬性的解析
當(dāng)我們應(yīng)用安裝或啟動(dòng)的過(guò)程中虾标,會(huì)對(duì)AndroidManifest.xml進(jìn)行解析,解析相關(guān)的代碼位于
platform/frameworks/base/core/java/android/content/pm/PackageParser.java:
public class PackageParser {
....
private boolean parseBaseApplication(Package owner, Resources res,
XmlResourceParser parser, int flags, String[] outError)
throws XmlPullParserException, IOException {
final ApplicationInfo ai = owner.applicationInfo;
final String pkgName = owner.applicationInfo.packageName;
// 獲取 AndroidManifest 的屬性
TypedArray sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestApplication);
....
// 獲取所設(shè)置的 persistent 值灌砖,默認(rèn)為 false
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_persistent,
false)) {
// 檢查應(yīng)用是否支持這個(gè)權(quán)限
final String requiredFeature = sa.getNonResourceString(com.android.internal.R.styleable
.AndroidManifestApplication_persistentWhenFeatureAvailable);
if (requiredFeature == null || mCallback.hasFeature(requiredFeature)) {
// 將 persistent 的 flag 設(shè)置到應(yīng)用信息中
ai.flags |= ApplicationInfo.FLAG_PERSISTENT;
}
}
....
}
....
}
解析后就會(huì)將應(yīng)用的各種信息保存在PKMS中的一個(gè)存儲(chǔ)所有應(yīng)用信息的一個(gè)Map中璧函,其中設(shè)置了persistent的應(yīng)用就包含了ApplicationInfo.FLAG_PERSISTENT標(biāo)志位,之后在系統(tǒng)的啟動(dòng)過(guò)程中就會(huì)根據(jù)這個(gè)標(biāo)志位控制應(yīng)用的啟動(dòng)基显。
persistent應(yīng)用的啟動(dòng)
persistent應(yīng)用的啟動(dòng)發(fā)生在AMS的systemReady方法內(nèi)蘸吓,這一部分通過(guò)PKMS獲取到所有persistent為true的應(yīng)用列表,之后對(duì)列表進(jìn)行遍歷撩幽,通過(guò)addAppLocked方法將應(yīng)用一個(gè)個(gè)啟動(dòng)起來(lái)库继。
對(duì)應(yīng)代碼的位于
/platform/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
....
// 該靜態(tài)常量用于判斷應(yīng)用是否persistent應(yīng)用
private static final int PERSISTENT_MASK =
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
// 當(dāng)系統(tǒng)服務(wù)啟動(dòng)時(shí),AMS執(zhí)行systemReady方法
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
....
synchronized (this) {
// 1.啟動(dòng)所有persistent屬性為true的應(yīng)用
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
....
}
}
....
void startPersistentApps(int matchFlags) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
synchronized (this) {
try {
// 從PKMS的應(yīng)用MAP中拿到所有具有FLAG_PERSISTENT標(biāo)志位的應(yīng)用
final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
.getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
for (ApplicationInfo app : apps) {
// 過(guò)濾掉包名為android的應(yīng)用
if (!"android".equals(app.packageName)) {
//2. 添加并啟動(dòng)該APP進(jìn)程
addAppLocked(app, null, false, null /* ABI override */);
}
}
} catch (RemoteException ex) {
}
}
}
}
獲得所有具有FLAG_PERSISTENT標(biāo)志位的應(yīng)用
platform/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public class PackageManagerService extends IPackageManager.Stub
implements PackageSender {
....
// 存放所有應(yīng)用的信息的Map
final ArrayMap<String, PackageParser.Package> mPackages =
new ArrayMap<String, PackageParser.Package>();
....
@Override
public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return ParceledListSlice.emptyList();
}
return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
}
private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
synchronized (mPackages) {
final Iterator<PackageParser.Package> i = mPackages.values().iterator();
final int userId = UserHandle.getCallingUserId();\
// 遍歷mPackages
while (i.hasNext()) {
final PackageParser.Package p = i.next();
if (p.applicationInfo == null) continue;
....
// 判斷應(yīng)用信息是否有FLAG_PERSISTENT標(biāo)志位
if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
&& (!mSafeMode || isSystemApp(p))
&& (matchesUnaware || matchesAware)) {
PackageSetting ps = mSettings.mPackages.get(p.packageName);
if (ps != null) {
ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
ps.readUserState(userId), userId);
if (ai != null) {
// 將應(yīng)用的ApplicationInfo添加進(jìn)列表
finalList.add(ai);
}
}
}
}
}
return finalList;
}
}
添加并啟動(dòng)應(yīng)用進(jìn)程
AMS內(nèi)有一個(gè)存放所有正在啟動(dòng)的persistent應(yīng)用的List:mPersistentStartingProcesses摸航,后續(xù)在啟動(dòng)應(yīng)用和重啟應(yīng)用時(shí)都會(huì)使用到該List制跟。
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
/**
* 正在啟動(dòng)的persistent應(yīng)用程序列表。
*/
final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
....
final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
String abiOverride) {
return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
abiOverride);
}
final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
boolean disableHiddenApiChecks, String abiOverride) {
// ProcessRecord是用于描述進(jìn)程的數(shù)據(jù)結(jié)構(gòu)
ProcessRecord app;
// 傳入的isolated為false
if (!isolated) {
// 第一次啟動(dòng)酱虎,這里查找應(yīng)用所在的進(jìn)程返回都為null
app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
info.uid, true);
} else {
app = null;
}
if (app == null) {
// 為應(yīng)用創(chuàng)建ProcessRecord
app = newProcessRecordLocked(info, customProcess, isolated, 0);
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
....
if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
app.persistent = true;
app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
}
// 整個(gè)啟動(dòng)過(guò)程是異步的雨膨,所以這里仍需要判斷應(yīng)用線程是否為null,同時(shí)判斷應(yīng)用是否正在啟動(dòng)中(在mPersistentStartingProcesses列表內(nèi))
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
// 應(yīng)用沒(méi)有在啟動(dòng)读串,則將應(yīng)用添加到mPersistentStartingProcesses列表
mPersistentStartingProcesses.add(app);
// 啟動(dòng)應(yīng)用
startProcessLocked(app, "added application",
customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
abiOverride);
}
return app;
}
....
}
系統(tǒng)啟動(dòng)時(shí)應(yīng)用的ProcessRecord都未創(chuàng)建聊记,所以在addAppLocked內(nèi)首先通過(guò)newProcessRecordLocked為應(yīng)用程序創(chuàng)建ProcessRecord,之后調(diào)用startProcessLocked來(lái)啟動(dòng)應(yīng)用程序恢暖,啟動(dòng)的過(guò)程不是這部分的重點(diǎn)排监,就不再詳細(xì)說(shuō)明。
persistent應(yīng)用啟動(dòng)完成
當(dāng)應(yīng)用啟動(dòng)完畢后就會(huì)調(diào)用到ActivityThread.java內(nèi)的attach方法杰捂,方法內(nèi)調(diào)用了AMS的attachApplication方法舆床,之后再到attachApplicationLocked,該方法內(nèi)部就會(huì)將應(yīng)用移除mPersistentStartingProcesses列表嫁佳,表明應(yīng)用啟動(dòng)完畢挨队,同時(shí)為應(yīng)用并注冊(cè)一個(gè)死亡監(jiān)聽(tīng)器AppDeathRecipient,用于應(yīng)用被異常殺死后的重啟蒿往。
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
....
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
....
final String processName = app.processName;
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
//如果注冊(cè)死亡接收器失敗盛垦,也會(huì)重新啟動(dòng)App進(jìn)程
startProcessLocked(app, "link fail", processName);
return false;
}
....
// 將應(yīng)用移除正在啟動(dòng)的持久性應(yīng)用列表
mPersistentStartingProcesses.remove(app);
....
}
}
persistent應(yīng)用死亡后重啟
當(dāng)應(yīng)用被殺死后,就會(huì)調(diào)用死亡接收器AppDeathRecipient的binderDied方法瓤漏,方法內(nèi)根據(jù)應(yīng)用是否是persistent應(yīng)用來(lái)控制是否重啟腾夯,整個(gè)流程如下:
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
....
private final class AppDeathRecipient implements IBinder.DeathRecipient {
final ProcessRecord mApp;
final int mPid;
final IApplicationThread mAppThread;
AppDeathRecipient(ProcessRecord app, int pid,
IApplicationThread thread) {
mApp = app;
mPid = pid;
mAppThread = thread;
}
@Override
public void binderDied() {
synchronized(ActivityManagerService.this) {
// 1. 調(diào)用appDiedLocked
appDiedLocked(mApp, mPid, mAppThread, true);
}
}
}
final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
boolean fromBinderDied) {
....
if (app.pid == pid && app.thread != null &&
app.thread.asBinder() == thread.asBinder()) {
....
// 2. 調(diào)用appDiedLocked
handleAppDiedLocked(app, false, true);
....
}
....
}
private final void handleAppDiedLocked(ProcessRecord app,
boolean restarting, boolean allowRestart) {
int pid = app.pid;
// 3. 調(diào)用appDiedLocked
boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
false /*replacingPid*/);
....
}
private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
....
// 判斷應(yīng)用是否是persistent應(yīng)用
if (!app.persistent || app.isolated) {
// 如果不是persistent應(yīng)用颊埃,則直接被清理掉
....
} else if (!app.removed) {
// 如果是persistent應(yīng)用,則保留相應(yīng)的信息
// 判斷其是否在待啟動(dòng)應(yīng)用程序mPersistentStartingProcesses列表
// 不在的話則添加蝶俱,并設(shè)置restart為true
if (mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
restart = true;
}
}
if (restart && !app.isolated) {
// 重新啟動(dòng)我們的應(yīng)用進(jìn)程
if (index < 0) {
ProcessList.remove(app.pid);
}
addProcessNameLocked(app);
app.pendingStart = false;
// 啟動(dòng)應(yīng)用程序進(jìn)程
startProcessLocked(app, "restart", app.processName);
return true;
} else if (app.pid > 0 && app.pid != MY_PID) {
// 不需要重啟的應(yīng)用
boolean removed;
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
}
app.setPid(0);
}
}
}
經(jīng)過(guò)這個(gè)過(guò)程之后班利,persistent屬性為true的應(yīng)用程序進(jìn)程就會(huì)被重啟。