APP 要工作在DBM (Direct Boot Mode)下的话,manifest 中加入:
<activity|provider|receiver|service ... android:directBootAware=”true”>
APP在进入DBM后会收到系统的广播消息: Intent.ACTION_LOCKED_BOOT_COMPLETED ——之前是开机完成,现在如果没有解锁。
用户解锁手机后,APP会收到另一条: Intent.ACTION_BOOT_COMPLETED —— 开机完成。
DBM下和正常模式下最大的不同是:使用一种新的存储空间:Device protected storage,在正常模式下是看不到这个空间的数据的,这样的话就可以做一些更加完备的安全机制,比如:
把网络连接的Tocken、SSH……放在此独立空间,防止用户平常使用时被其他APP侦听、窃取。
还有一点:DBM模式下的APP只能和同在此模式中的APP通信,貌似是废话哦,这个阶段其他APP也没跑起来呢。
最后一点:一台安装了Android N的设备,第一次使用要创建这个Device protected storage加密分区,方式有:
在ActivityManagerService的systemReady函数中:
public void systemReady(final Runnable goingCallback) {............startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);............
}
从上面的代码可以看出,systemReady将调用startPersistentApps启动某一类Application。
private void startPersistentApps(int matchFlags) {........synchronized (this) {try{final List<ApplicationInfo> apps = AppGlobals.getPackageManager().getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();for (ApplicationInfo app : apps) {if (!"android".equals(app.packageName)) {addAppLocked(app, false, null );}}}catch (RemoteException ex) {}}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
从上面的代码,我们知道PhoneApp将有addAppLocked进行处理:
final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, String abiOverride) {.........startProcessLocked(app, "added application", app.processName, abiOverride,null , null );.........
}private final void startProcessLocked(........) {.........Process.ProcessStartResult startResult = Process.start(entryPoint,app.processName, uid, uid, gids, debugFlags, mountExternal,app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,app.info.dataDir, entryPointArgs);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
在ActivityThread.java的main函数中:
.........
ActivityThread thread = new ActivityThread();
thread.attach(false);
.........
继续看看attach函数:
private void attach(boolean system) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {.............RuntimeInit.setApplicationObject(mAppThread.asBinder());final IActivityManager mgr = ActivityManagerNative.getDefault();try {mgr.attachApplication(mAppThread);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}...........}..............
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
从上面的代码可以看出,流程再次回到了ActivityManagerService:
@Override
public final void attachApplication(IApplicationThread thread) {synchronized (this) {int callingPid = Binder.getCallingPid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid);Binder.restoreCallingIdentity(origId);}
}private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {...........thread.bindApplication(.....);...........
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
我们看看ApplicationThreadNative.java中ApplicationThreadProxy的bindApplication函数:
class ApplicationThreadProxy implements IApplicationThread {
............@Overridepublic final void bindApplication(....) {........mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);........}
}
在ActivityThread.java中的handler H的handleMessage处理消息(在PhoneApp中的binder解析完收到的数据后,触发BIND_APPLICATION消息给H):
.............
case BIND_APPLICATION:Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");AppBindData data = (AppBindData)msg.obj;handleBindApplication(data);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;
............
private void handleBindApplication(AppBindData data) {..........try {mInstrumentation.callApplicationOnCreate(app);} catch (Exception e) {........}........
}
public void callApplicationOnCreate(Application app) {app.onCreate();
}