Android Auto-Boot Analysis
1.1 实现 Android 系统的自启动
1.1.1.实现自己的广播接收器,在 onReceive()方法中实现要处理的逻辑
1.1.2. AndroidManifest.xml 中注冊该广播接收器,申明接收广播过滤器为Boot_Completed 广播
1.1.3.申明权限
实现 Android 的自启动与一般的广播接收没有非常大差别,可是有一些要注意的地方:
1.在使用 BOOT_COMPLETED 广播时,必须要 RECEIVE_BOOT_COMPLETED 权限,这是 4.0 后的改动
2.通过指定 priority 属性能够设置 BOOT_COMPLETED 广播的优先级,让该app 早于其它 app 接收到广播
3.在 4.4 下 BOOT_COMPLETED 广播是有序广播,可是不可中断(指定了FLAG_RECEIVER_NO_ABORT 字段),而在 4.4 曾经,BOOT_COMPLETED 广播
是无序的
1.在使用 BOOT_COMPLETED 广播时,必须要 RECEIVE_BOOT_COMPLETED 权限,这是 4.0 后的改动
2.通过指定 priority 属性能够设置 BOOT_COMPLETED 广播的优先级,让该app 早于其它 app 接收到广播
3.在 4.4 下 BOOT_COMPLETED 广播是有序广播,可是不可中断(指定了FLAG_RECEIVER_NO_ABORT 字段),而在 4.4 曾经,BOOT_COMPLETED 广播
是无序的
4.由于 4.0 后添加了 Package stopped 标志,因此处于该状态下的 app 无法收到 BOOT_COMPLETED 广播时,该状态由下面情况产生:
a. 通过反射调用隐藏接口 forceStopPackage 接口停止的应用
b.在 settingapplicationdetail 中点 disable button,被停用的应用
c.新安装完毕,从未打开和执行过的应用
a. 通过反射调用隐藏接口 forceStopPackage 接口停止的应用
b.在 settingapplicationdetail 中点 disable button,被停用的应用
c.新安装完毕,从未打开和执行过的应用
1.2 BOOT_COMPLETED 广播发送的时机
要了解 BOOT_COMPLETED 广播的发送时机就必须了解 Android 的启动流程,
简要了解 Android 的启动顺序:
1 系统启动,bootloader
2 SystemServer
3 AMS
4 Send systemReady 信号
5 Launcher start
6 Send finishBooting 信号
7 发送 BOOT_COMPLETED 广播
简要了解 Android 的启动顺序:
1 系统启动,bootloader
2 SystemServer
3 AMS
4 Send systemReady 信号
5 Launcher start
6 Send finishBooting 信号
7 发送 BOOT_COMPLETED 广播
1.3 禁止自启动的原理
通过了解 BOOT_COMPLETED 广播发送的时机和原理,我们大概能够分析出禁止自启动的几种方法:
1. 阻止应用收到 BOOT_COMPLETED 广播,在 4.0 以后,能够通过设置 app 的Package stopped 标志来实现(反射调用隐藏的 forceStopPackage 方法)
2. 通过停用应用的广播接收器来屏蔽 BOOT_COMPLETED 广播,即设置组件的android:enable 属性来停止该接收器的响应
3. 通过 kill 进程来将自启动的 app 结束掉
1. 阻止应用收到 BOOT_COMPLETED 广播,在 4.0 以后,能够通过设置 app 的Package stopped 标志来实现(反射调用隐藏的 forceStopPackage 方法)
2. 通过停用应用的广播接收器来屏蔽 BOOT_COMPLETED 广播,即设置组件的android:enable 属性来停止该接收器的响应
3. 通过 kill 进程来将自启动的 app 结束掉
1.4 禁止自启动的方法
1.4.1 forceStopPackage
通过 forceStopPackage 去禁用,不仅会停用 app 的组件,也会停止他的定时器等,同一时候须要 system 权限和系统签名。
1.4.2 停用组件方法
Android 文档中对 Android 的组件有例如以下描写叙述:
The<application> element has its own enabled attribute that applies to allapplication components, including broadcast receivers.
即我们能够设置一个组件是否启用。
PackageManager 中提供下面两个方法:
The<application> element has its own enabled attribute that applies to allapplication components, including broadcast receivers.
即我们能够设置一个组件是否启用。
PackageManager 中提供下面两个方法:
setApplicationEnabledSetting 能够停用应用中全部的组件。
setComponentEnabledSetting 能够停用指定的组件。
该方法有下面几个须要注意的地方:
a.与 forceStopPackage 接口相比,该接口不会清空定时器等,仅仅会启用、停用组件,因此在定时器中发送自己定义广播,而且在广播中指定FLAG_EXCLUDE_STOPPED_PACKAGES 是能够唤醒组件。
b.使用 setComponentEnabledSetting 接口必须是 system 程序并具有system 签名
c.须要申明 CHANGE_COMPONENT_ENABLED_STATE 权限
用法:
非常遗憾,该方法仅仅能对自己的 app 改动,而操作第三方 app 须要 system权限,即使 root 也无法使用,因此,我们须要利用 packagemanager 的cmd 实现,即 PM 命令。
命令须要 root 权限:pm enable/disable package/package.class
命令须要 root 权限:pm enable/disable package/package.class
1.4.3 Kill 进程方法
最经常使用的方法是通过 ActivityManager 类中的killBackgroundProcesses 接口来杀死进程,通用代码例如以下:
可是该方法清理的进程等级不是太高,killProcess(pid)是一种能 kill更高优先级的方法,可是该方法并不能保证进程被 kill,由于该方法仅仅是发出 kill process 的信号,详细是否要 kill 是由系统决定的,一般来说,能够被杀死的进程例如以下:
a. 同包下进程
b. 同 uid 进程
c. 由本 app 在执行时生成的进程
a. 同包下进程
b. 同 uid 进程
c. 由本 app 在执行时生成的进程
1.5 查找开机启动权限的 apk
查找权限的方法有非常多,这里仅仅提供一种,即通过 packagemnager 来实现:
1.6 总结
综上,市场上一般的自启动管理 app,大多是通过获取 root 权限后使用 pm命令来禁用包含 Boot_Completed 的接收器来实现的,另一些则是通过监控后台进程,轮询查找黑名单中的进程来 kill 掉对应的自启动程序,不仅包含开机自启动,还能够监控后台自启动,只是该方法的最大问题就是添加了系统消耗,包含内存消耗和电量消耗。
另外另一些第三方的 ROM 也带有权限管理工具,比如小米的权限管理系统,是在解析接收器的权限的时候,会将全部接收器的优先级减 1,这样其它应用的优先级将永远低于其系统 app 的优先级。
通过调查发现,用户清理进程,控制开机启动的习惯是从 windows 開始的,进程清理或者说是控制开机启动项对于 Android 系统来说并没有非常大意义,假设一个 Android 系统不 root,那么第三方 app 对系统方面的控制权限基本没有,使用这些软件,一方面减少了 Android 系统的安全性,另一方面也会消耗非常大的系统资源,造成恶性循环,手机越用越慢。