需求:需要开机完成拉起系统应用服务
代码路径:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
frameworks/base/core/java/android/content/pm/PackageUserState.java
1、在ActivityManagerService.java文件中finishBooting()文件中启动应用的服务,launchAppWhenBootComplete()该方法中就是被拉起的服务
final void finishBooting() {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
synchronized (this) {
if (!mBootAnimationComplete) {
mCallFinishBooting = true;
return;
}
mCallFinishBooting = false;
}
ArraySet completedIsas = new ArraySet();
for (String abi : Build.SUPPORTED_ABIS) {
ZYGOTE_PROCESS.establishZygoteConnectionForAbi(abi);
final String instructionSet = VMRuntime.getInstructionSet(abi);
if (!completedIsas.contains(instructionSet)) {
try {
mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
} catch (InstallerException e) {
if (!VMRuntime.didPruneDalvikCache()) {
// This is technically not the right filter, as different zygotes may
// have made different pruning decisions. But the log is best effort,
// anyways.
Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
e.getMessage() +")");
}
}
completedIsas.add(instructionSet);
}
}
IntentFilter pkgFilter = new IntentFilter();
pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
pkgFilter.addDataScheme("package");
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
if (pkgs != null) {
for (String pkg : pkgs) {
synchronized (ActivityManagerService.this) {
if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
0, "query restart")) {
setResultCode(Activity.RESULT_OK);
return;
}
}
}
}
}
}, pkgFilter);
IntentFilter dumpheapFilter = new IntentFilter();
dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final long delay = intent.getBooleanExtra(
DumpHeapActivity.EXTRA_DELAY_DELETE, false) ? 5 * 60 * 1000 : 0;
mHandler.sendEmptyMessageDelayed(DELETE_DUMPHEAP_MSG, delay);
}
}, dumpheapFilter);
// Inform checkpointing systems of success
try {
// This line is needed to CTS test for the correct exception handling
// See b/138952436 for context
Slog.i(TAG, "about to commit checkpoint");
IStorageManager storageManager = PackageHelper.getStorageManager();
storageManager.commitChanges();
} catch (Exception e) {
PowerManager pm = (PowerManager)
mContext.getSystemService(Context.POWER_SERVICE);
pm.reboot("Checkpoint commit failed");
}
// Let system services know.
mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
synchronized (this) {
// Ensure that any processes we had put on hold are now started
// up.
final int NP = mProcessesOnHold.size();
if (NP > 0) {
ArrayList procs =
new ArrayList(mProcessesOnHold);
for (int ip=0; ip
遇到问题点:
在这里拉起服务,会报如下异常
2021-10-14 18:02:35.171 18511-18538/system_process W/ActivityManager: Unable to start service Intent { cmp=com.wq.test.Service } U=0: not found
分析流程:
根据日志分析,最后找到该日志是在ActiveServices.java类中retrieveServiceLocked()方法中打印的
if (r == null) {
try {
int flags = ActivityManagerService.STOCK_PM_FLAGS
| PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
if (allowInstant) {
flags |= PackageManager.MATCH_INSTANT;
}
// TODO: come back and remove this assumption to triage all services
ResolveInfo rInfo = mAm.getPackageManagerInternalLocked().resolveService(service,
resolvedType, flags, userId, callingUid);
ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
if (sInfo == null) {
Slog.w(TAG_SERVICE, "Unable to start service " + service + " U=" + userId +
": not found");
return null;
}
if (instanceName != null
&& (sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
throw new IllegalArgumentException("Can't use instance name '" + instanceName
+ "' with non-isolated service '" + sInfo.name + "'");
}
ComponentName className = new ComponentName(
sInfo.applicationInfo.packageName, sInfo.name);
ComponentName name = comp != null ? comp : className;
原因:
Android N 引入了一个新的特性 Direct Boot Mode ,设备启动后进入一个新的模式,直到用户解锁后,此模式才会消失。此时若想启动应用,应用必须先向系统注册其组件,然后才能在Direct Boot Mode 模式下运行或访问设备加密存储。 应用通过将组件标记为“加密感知”来注册系统。 若要将您的组件标记为加密感知,请在AndroidManifest.xml中将 android:directBootAware 属性设为 true。
解决方案
在AndroidManifest.xml文件中application标签中添加directBootAware属性,我们SystemUI中启动SystemUIService服务也是添加该标签
android:directBootAware="true"



