文章摘要:
1、BOOT_COMPLETED在ActivityManagerService中由系统发送。
2、应用可以监听该广播,成为自启动权限,但是这样会有很多缺点,最大的缺点就是拖慢开机进度,影响用户体验。
3、开机状态会sys.boot_completed,可以通过该属性状态得到开机状态。
一、BOOT_COMPLETED广播是什么?
1、BOOT_COMPLETED是系统在开机加载完毕后发送的。如下:
/**
* Broadcast Action: This is broadcast once, after the system has finished
* booting. It can be used to perform application-specific initialization,
* such as installing alarms. You must hold the
* {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission
* in order to receive this broadcast.
*
*
This is a protected intent that can only be sent
* by the system.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
从注释可以看出,该广播需要权限才能接收,并且只有系统有权限发送它。
2、接收BOOT_COMPLETED广播,需要权限,该权限:android.Manifest.permission#RECEIVE_BOOT_COMPLETED。
如下是系统对该权限的介绍:
android:permissionGroup="android.permission-group.APP_INFO"
android:protectionLevel="normal"
android:label="@string/permlab_receiveBootCompleted"
android:description="@string/permdesc_receiveBootCompleted" />
a、从ProtectionLevel来看,应用可以申请该权限。android:protectionLevel="normal"
b、如文中所述,申请该权限,有许多缺点。
I、增加系统启动的时间。因为系统启动过程中,广播接收方会收到广播,并可以启动自身或者加载某些资源。
II、自启动,不经用户确认。应用都说在用户的点击或者请求发起下启动的,自启动可以绕过用户,自我自动。
III、不要想着自己的小行为用户觉察不到,系统会将自启动的应用程序形成一份列表名单,show给用户,并交由用户管理。
隐私授权
二、如何接收该广播。
1、前面提到了,接收BOOT_COMPLETED广播,需要权限,该权限:android.Manifest.permission#RECEIVE_BOOT_COMPLETED。
在AndroidManifest.xml中增加权限信息:
2、增加广播注册。
在AndrodManifest.xml中,增加广播注册信息:
三、BOOT_COMPLETED系统如何发送的。
1、在系统启动的过程中,ActivityManagerServie发送的该广播。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java#finishBooting
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
// Start looking for apps that are abusing wake locks.
Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
// Tell anyone interested that we are done booting!
SystemProperties.set("sys.boot_completed", "1");
// And trigger dev.bootcomplete if we are not showing encryption progress
if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
|| "".equals(SystemProperties.get("vold.encrypt_progress"))) {
SystemProperties.set("dev.bootcomplete", "1");
}
for (int i=0; i
UserStartedState uss = mStartedUsers.valueAt(i);
if (uss.mState == UserStartedState.STATE_BOOTING) {
uss.mState = UserStartedState.STATE_RUNNING;
final int userId = mStartedUsers.keyAt(i);
Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
broadcastIntentLocked(null, null, intent, null,
new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode,
String data, Bundle extras, boolean ordered,
boolean sticky, int sendingUser) {
synchronized (ActivityManagerService.this) {
requestPssAllProcsLocked(SystemClock.uptimeMillis(),
true, false);
}
}
},
0, null, null,
android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
userId);
}
}
scheduleStartProfilesLocked();
}
2、从上面粘贴的代码中,我们可以得出如下结论。
a、开机启动广播,是区分多用户的。
b、在开机广播发送的流程中,会向系统写入sys.boot_completed,我们依据它可以得出当前系统是否已开机加载结束,这对一些系统服务或者app判断应用状态很有效。
SystemProperties.set("sys.boot_completed", "1");