android 7.0 加入 android:directBootAware之关机闹钟无声
2017-11-29 15:46
169 查看
问题
最近遇到关机后,之前设置的闹钟无声的问题,解决办法是在MediaProvider的AndroidMenifest.xml中加入android:directBootAware<application android:process="android.process.media" android:label="@string/app_label" android:allowBackup="false" android:directBootAware="true" android:supportsRtl="true">
新特性Direct Boot Mode
Android N引入了一个新特性: Direct Boot Mode—— 设备启动后进入的一个新模式,直到用户解锁(unlock)设备此阶段结束。在此 Direct Boot Mode 下 APP 主要使用在如果情况
Alarm、clock 类的操作
需要做重要的或紧急的通知
底层服务类
使用场景的话,如手机丢了,捡到的人解不开锁,也做不了啥操作,现在任意工作在Direct Boot Mode 下的APP都可以“安全地”跑起来,和服务器建链,可以全方位的和捡手机的人进行沟通或拍照。
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加密分区,方式有:
设备的setting中修改:Settings > Developer options > Convert to file encryption
fastboot中修改:
$ adb reboot-bootloader $ fastboot --wipe-and-use-fbe
在ActivityManagerService的systemReady函数中:
public void systemReady(final Runnable goingCallback) { ............ //注意此处的参数MATCH_DIRECT_BOOT_AWARE startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); ............ }
从上面的代码可以看出,systemReady将调用startPersistentApps启动某一类Application。
private void startPersistentApps(int matchFlags) { ........ synchronized (this) { try{ //从PackageManagerService中获取同时具有Persistent和directBootAware标签的应用列表 final List<ApplicationInfo> apps = AppGlobals.getPackageManager() .getPersistentApplications(STOCK_PM_FLAGS | matchFlags) .getList(); for (ApplicationInfo app : apps) { if (!"android".equals(app.packageName)) { //启动这些应用 addAppLocked(app, false, nu 4000 ll /* ABI override */); } } }catch (RemoteException ex) { } } }
从上面的代码,我们知道PhoneApp将有addAppLocked进行处理:
final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, String abiOverride) { ......... startProcessLocked(app, "added application", app.processName, abiOverride, null /* entryPoint */, null /* entryPointArgs */); ......... } private final void startProcessLocked(........) { ......... //这里之前的blog提到过,将利用socket发送消息给zygote分裂出应用所需的进程 //进程创建出后,将调用对应类的main函数,对于PhoneApp而言,即android.app.ActivityThread 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); }
在ActivityThread.java的main函数中:
......... ActivityThread thread = new ActivityThread(); //PhoneApp不是系统App thread.attach(false); .........
继续看看attach函数:
private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { ............. RuntimeInit.setApplicationObject(mAppThread.asBinder()); //binder通信,获取Remote端 final IActivityManager mgr = ActivityManagerNative.getDefault(); try { //将ApplicationThread传给AM,实际上传递的是binder代理 mgr.attachApplication(mAppThread); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } ........... }..............
从上面的代码可以看出,流程再次回到了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) { ........... //将调用ApplicationThread的bindApplication thread.bindApplication(.....); ...........
我们看看ApplicationThreadNative.java中ApplicationThreadProxy的bindApplication函数:
class ApplicationThreadProxy implements IApplicationThread { ............ @Override public final void bindApplication(....) { ........ //利用binder通信,ActivityManagerService将消息发回给PhoneApp中的ActivityThread 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(); }
相关文章推荐
- android 7.0 加入 android:directBootAware之关机闹钟无声
- android 7.0 加入 android:directBootAware之关机闹钟无声
- android 7.0 加入 android:directBootAware之关机闹钟无声
- android 7.0 加入 android:directBootAware之关机闹钟无声
- android 7.0 加入 android:directBootAware之关机闹钟无声
- android 7.0 加入 android:directBootAware
- Android AlarmManager加入与取消闹钟提醒, Notification不显示的问题
- android&nbsp;关机闹钟
- 在u-boot里面加入Android lk bootloader的一键烧写功能(3)
- android 关机闹钟
- android&nbsp;关机闹钟
- Android 动态logo bootanimation.zip 制作与关机log
- android 关机闹钟
- android智能机低电关机后关机闹钟不响的原因及解决方案
- android_N上关机闹钟铃声问题_设置的铃声和播放的铃声不一样
- 在u-boot里面加入Android lk bootloader的一键烧写功能(1)
- android关机闹钟设计思路
- Android N新特性 : Direct Boot Mode[DBM]
- android 关机闹钟
- [置顶] android关机闹钟设计思路