android APP开机自启BOOT_COMPLETED广播与android:persisten属性对比
情况1,
没有在APP的项目清单AndroidMainfest.xml文件内注册静态开机广播 android.intent.action.BOOT_COMPLETED,也就是说此APP在没有用户操作去启动它,它是不会自动运行,
现测试 其是否可以通过其它APP直接显式startService启动此APP的某个service服务,从而达到启动此APP的目标,此处我在package/provider/TelephonyProvider以发关键字短信的方式来启动APP的一个service
在aosp/packages/providers/TelephonyProvider/src/com/android/providers/telephony/SmsProvider.java类的对手机接收的短信做一个简单的判断,来启动APP内的一个service
Intent intent= new Intent();
intent.putExtra("address", address);
intent.setComponent(new android.content.ComponentName("com.xxx.androidodm","com.xxx.androidodm.MainService"));//此处 必须显示的指定Component变量,即要启动的包名与Service类名
getContext().startService(intent); //service 方式启动
// 记得在你的service设置该两属性,否则会不允许跨进程启动它,
android:enabled="true"
android:exported="true"
android:exported 是Android中的四大组件 Activity,Service,Provider,Receiver 四大组件中都会有的一个属性。它表示是否支持其它应用调用当前组件。如果Service等的AndroidManifest中声明为android:exported="false"则该服务不能够跨进程使用。如果设置为true,则能够被调用或交互,否则不能。设置为false时,只有同一个应用程序的组件或带有相同用户ID的应用程序才能启动或绑定该服务。
//intent.setAction("com.xxx.andrdoidodm,customaction");//广播方式一般都会添加一个动作
getContext().sendBroadcast(intent); //广播方式启动
广播方式启动相比service 方式启动反应要慢一点,
LOG输出:
09-04 10:02:15.130 26138 26347 D SmsProvider: insertInner url=content://sms/raw, match=15
09-04 10:02:15.130 26138 26347 D SmsProvider: insertInner RAWINBOX messagebody =xxx
09-04 10:02:15.213 26138 27335 D SmsProvider: Query url=content://sms, match=0
09-04 10:02:15.240 28959 28959 I androidodm: Application oncreate //此处是APP的Application的oncreate方法内LOG标记
09-04 10:02:15.294 28959 28959 D androidodm: MainService onCreate //此处是APP的MainService的oncreate方法内LOG标记
结论:当APP在未启动运行的状态下可以通过在其它APP内以启动此APP的某一service方式 / 广播方式启动来启动此APP进入运行状态,广播方式启动相比service 方式启动反应要慢一点,而在启动APP先,无论如何都是先启动此APP的APPlication的继承类开始执行(必须先创建APP的进程然,这是service生存的依赖,后再开启进程内的某service或是广播,不可能说某service没有运行在任何应用进程内,)
情况2
对比APP静态注册开机广播通过接收开机广播再自启APP 与 在APP的AndroidManifest.xml文件中设置属性:android:persistent属性系统自启的时间快慢
<application
android:persistent="true"> //android:persisten是application节点属性,
</application>
以下是android源码内自带的APP有设置android:persisten属性的所有应用,
接下来在自己的应用内也添加此属性android:persisten,并在应用源码中的Application的继承类中与MainActivity类中添加LOG输出
LOG打印:
如上图,分别在APP的Application继承类中 与 静态注册的开机广播接收类中分别打印log,很时显在Application类中打印的时间要比开机广播中打印的时间早30秒左右,
也就是说通过设置属性 android:persistent="true"开机自启APP的时间要比通过接收开机广播来自启APP的时间快30秒钟。
既然 android:persistent="true"是应用节点Application属性,如果我们在应用中不重写Application类,即如下图中删除android:name=".XXApplication"此行,是否仍会将应用在开机时启动它,
测试结果是即使在应用中并未重写application类的子类,只要你在AndroidManifest.xml文件中声明了该android:persistent="true"属性,那么系统开机时就一定会自动启动APP,创建这APP进程,无论你没有重写application类的子类, 虽然没有打印出我们在MainActivity类中的添加的log,但我们通过adb shell命令查看系统中是否有我们APP的包名进程存在,查看命令是:adb shell ps|grep "your packagename"
另外APP的MainActivity类中也有添加Log 但未打印出来,说明通过设置android:persistent="true"属性开机自动APP,并不会去启动其中的Activity,只会启动Application的继承类,这原因后面继续分析
评论