Android那些事儿Android开发Android技术知识

关于BOOT_COMPLETED广播-自启动

2016-11-26  本文已影响6722人  Android那些事儿

文章摘要:
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.
     *
     * <p class="note">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。
如下是系统对该权限的介绍:

    <!-- Allows an application to receive the
         {@link android.content.Intent#ACTION_BOOT_COMPLETED} that is
         broadcast after the system finishes booting.  If you don't
         request this permission, you will not receive the broadcast at
         that time.  Though holding this permission does not have any
         security implications, it can have a negative impact on the
         user experience by increasing the amount of time it takes the
         system to start and allowing applications to have themselves
         running without the user being aware of them.  As such, you must
         explicitly declare your use of this facility to make that visible
         to the user. -->
    <permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"
        android:permissionGroup="android.permission-group.APP_INFO"
        android:protectionLevel="normal"
        android:label="@string/permlab_receiveBootCompleted"
        android:description="@string/permdesc_receiveBootCompleted" />
隐私授权

二、如何接收该广播。
1、前面提到了,接收BOOT_COMPLETED广播,需要权限,该权限:android.Manifest.permission#RECEIVE_BOOT_COMPLETED。
在AndroidManifest.xml中增加权限信息:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

2、增加广播注册。
在AndrodManifest.xml中,增加广播注册信息:

<receiver android:name="com.example.androidtest.BootCompleteReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

三、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<mStartedUsers.size(); 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、从上面粘贴的代码中,我们可以得出如下结论。

SystemProperties.set("sys.boot_completed", "1");
上一篇下一篇

猜你喜欢

热点阅读