转自:http://blog.youkuaiyun.com/ocean2006/article/details/40806819
概要
工作中遇到一个问题:监控应用的后台Service需要一直运行不退出。为了选用合适的方法,搜索了网上常用保持进程或者Service不被杀死的方法,监听开机广播、解锁屏广播等有规律广播是很好的选择。当应用运行在android2.x版本上时一切正常,但是在android4.x版本上发现应用被用户在系统Settings中强制force stop后,无法监听到此类广播,导致监控应用不能正常运行。
调查发现,这是android系统在3.1版本以后为了加强系统安全性和优化性能对系统广播进行了限制。
Service运行不退出的常用方法
1. 应用监控开机广播boot_completed、解锁屏广播user_present、网络连接状态改变广播CONNECTIVITY_CHANGE等有规律的系统广播
--android3.1以后,首次安装未启动或者用户强制force stop后,应用无法监听到
--应用启动后,可以接收到上述广播,但是会导致手机启动变慢,耗电明显
2. 放到系统应用system/app/或者system/priv-app/目录下永远可以监听1中的广播
--仅适用于预装应用,或者手机已经root可以操作系统目录
3. 设置应用的application属性persistent为true,保证应用开机后一直后台运行
--仅适用于系统应用,第三方应用无效果
4. 开启两个独立应用进程,相互监控,一方被kill,由对方立即启动
--一个应用内开启两个进程,android3.1以后被用户force stop后依然无法监听到1中的广播
--开启两个独立应用进程,首次启动后可以实现相互监控。但是用户体验不好,需要安装两个apk。
5. Service中调用AlarmManager的定时器功能,周期性检查启动Service
--由于pending Intent由系统AlarmManager发送,android3.1以后应用被force stop后无法收到
--定期发送造成应用耗电明显
6. Service内部处理,保证不退出
--在onStartCommand中设置start_sticky的返回值,可以保证Service因内存不足被kill、内存可用时被重启
--在onDestory时重启该Service
--提高Service优先级:调用startForeground设置service为前台
--应用被force stop后这些方法无效
不过在android3.1以后的版本上,对于第三方APK,上述几种方法仅能尽量保证进程或者service不退出,但不是100%保证。
Android对于系统广播的控制
从Android3.1开始,android对于系统发送的广播进行了限制,原文如下:
- Launch controls on stoppedapplications
- Starting from Android 3.1, the system's package manager keeps track ofapplications that are in a stopped state and provides a means
- of controllingtheir launch from background processes and other applications.
- Note that an application's stopped state is not the same as an Activity'sstopped state. The system manages those two stopped states
- separately.
- The platform defines two new intent flags that let a sender specifywhether the Intent should be allowed to activate components in
- stoppedapplication.
- FLAG_INCLUDE_STOPPED_PACKAGES —Include intent filters of stopped applications in the list of potential targetsto resolve against.
- FLAG_EXCLUDE_STOPPED_PACKAGES —Exclude intent filters of stopped applications from the list of potentialtargets.
- When neither or both of these flags is defined in an intent, the defaultbehavior is to include filters of stopped applications in
- the list ofpotential targets.
- Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGESto all broadcastintents. It does this to prevent broadcasts from background
- services frominadvertently or unnecessarily launching components of stoppped applications.A background service or application can
- override this behavior by adding theFLAG_INCLUDE_STOPPED_PACKAGES flag to broadcastintents that should be allowed to activate stopped
- applications.
- Applications are in a stopped state when they are first installed but are notyet launched and when they are manually stopped by the
- user (in ManageApplications).
Android官方API说明:http://developer.android.com/about/versions/android-3.1.html#launchcontrols
对于上述描述总结如下:
1.在Android3.1以后版本添加了标志FLAG_INCLUDE_STOPPED_PACKAGES和FLAG_EXCLUDE_STOPPED_PACKAGES,用于区分发送广播时是否启动激活那些未启动过或者被用户force stop的应用组件。当两个Flag都不设置或都设置的时候,默认操作是FLAG_INCLUDE_STOPPED_PACKAGES。
2.系统向所有的Intent的广播添加了FLAG_EXCLUDE_STOPPED_PACKAGES标志。它这样做是为了防止广播无意中的或不必要地开启组件的stoppped应用程序的后台服务。这样可以优化系统性能,提高安全性,不过对于监控类软件是一个沉重的打击。
3.用户给自定义的广播Intent添加FLAG_INCLUDE_STOPPED_PACKAGES,用于启动stop状态的应用组件。但是系统自带的广播intent,我们无能为力。
综上,在android3.1以后,系统加强了广播的限制,对于进程或者service长时间运行不退出没有有效的解决方案。总体来看,启动两个独立应用进程是一个不错的选择,一旦用户启动应用后,即使点击force stop,也可以由另一个应用启动。
601

被折叠的 条评论
为什么被折叠?



