android APP开机自启BOOT_COMPLETED广播与android:persisten属性对比

sancaiodm Android应用 2021-09-04 1635 0

情况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输出:

image.png

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属性的所有应用,

image.png

接下来在自己的应用内也添加此属性android:persisten,并在应用源码中的Application的继承类中与MainActivity类中添加LOG输出

LOG打印:

image.png

如上图,分别在APP的Application继承类中 与 静态注册的开机广播接收类中分别打印log,很时显在Application类中打印的时间要比开机广播中打印的时间早30秒左右, 

也就是说通过设置属性 android:persistent="true"开机自启APP的时间要比通过接收开机广播来自启APP的时间快30秒钟。


既然 android:persistent="true"是应用节点Application属性,如果我们在应用中不重写Application类,即如下图中删除android:name=".XXApplication"此行,是否仍会将应用在开机时启动它,

image.png

测试结果是即使在应用中并未重写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的继承类,这原因后面继续分析

评论