Android在第三方应用程序系统应用尽早开始,杀死自己主动的第三方应用程序,以重新启动
1.为什么第三方应用程序可能早于System的app启动?
Android能够查阅了,这里就不细述了,这里不阐述ROM启动还有bootloader。软件启动的大致流程应该是
- 启动kernel
- 执行servicemanager 把一些native的服务用命令启动起来(包含wifi, power, rild, surfaceflinger, mediaserver等等)
- 启动Dalivk中的第一个进程Zygote -> 启动java 层的系统服务system_server(包含PowerManagerService, ActivityManagerService , telephony.registry, DisplayManagerService等等)该服务中的这些部件跟native的那些服务关联在一起
- 启动Luncher和Persistent的App,该程序是系统级的在AndroidManifest.xml里声明android:persistent="true"
- 发出ACTION_BOOT_COMPLETED广播给其它应用。
在这里须要注意的是声明android:persistent属性为true的APP被kill掉后还是会自己主动重新启动的。系统中我们已知android:persistent属性为true的APP肯定有Phone App,也就是说第三方应用应当至少晚于Phone APP启动,怎样推断呢?最简单的办法看其PID的大小,PID值越小越先启动。有其第三方应用能够先于Phone APP启动。我们探其应用的AndroidManifest.xml (PS:怎样看APK的代码,网上有你懂的apktool等),发现其在AndroidManifest里定义的静态Receiver的intent-filter的属性例如以下:
<receiver android:name="com.anguanjia.safe.AAAReceiver">
<intent-filter android:priority="2147483647"></span>
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.intent.action.ANY_DATA_STATE" />
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
<intent-filter android:priority="2147483647">
<action android:name="android.intent.action.MEDIA_UNMOUNTED" />
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.MEDIA_REMOVED" />
<action android:name="android.intent.action.MEDIA_CHECKING" />
<action android:name="android.intent.action.MEDIA_EJECT" />
<data android:scheme="file" />
</intent-filter>
2147483647 这个值是什么?好大,哦,原来是int的最大值!
我们来看下google 文档
android:priority
The priority that should be given to the parent component with regard to handling intents of the type described by the filter. This attribute has meaning for both activities and broadcast receivers:
It provides information about how able an activity is to respond to an intent that matches the filter, relative to other activities that could also respond to the intent. When an intent could be handled by multiple activities with different priorities,
Android will consider only those with higher priority values as potential targets for the intent.
It controls the order in which broadcast receivers are executed to receive broadcast messages. Those with higher priority values are called before those with lower values. (The order applies only to synchronous messages; it's ignored for asynchronous
messages.)
Use this attribute only if you really need to impose a specific order in which the broadcasts are received, or want to force Android to prefer one activity over others.
The value must be an integer, such as "100". Higher numbers have a higher priority. The default value is 0. The value must be greater than -1000 and less than 1000.
这个值是receiver的优先级,值越大优先级越高,按优先顺序运行,可是文档介绍优先级值大小是-1000~1000. 该应用的是int的最大值, 但android平台没有对android:priority值进行检查。在开机后该应用Receiver的intent-filter的优先级最高,在该filter里的intent被系统发送出来(android.intent.action.MEDIA_MOUNTE,
android.net.wifi.WIFI_STATE_CHANGED等等),这个时候App会依据这个intent而被启动起来。
这里须要注意的是该Receiver是个静态的,一定是要注冊在AndroidManifest里。
当Wifi成功注冊后会发出WIFI_STATE_CHANGED的消息, 或者其它的部件完毕一些事件后也会发出类似的消息。而这些消息的发出又早于属性为persistent的系统级APP的启动, 由此就会发生第三方应用早于系统级APP的启动的情况。
2. 在Android手机上为什么我想全然关闭的程序关不了?
有一种理论是Android手机为了有更好的用户体验。会后台自己主动启动一些程序。 这样我们前台在操作的时候会感觉手机更流畅平滑。
可是假设程序执行过多。对CPU 内存的开销过大,往往会导致系统越用越慢,乃至手机挂掉的问题,在内存管理这快Android有两种机制去解决问题,一个是在framework层在 trimApplication方法中去实现,另外一个就是在kernel里的lowmemorykiller。 这里不再细述。
可是对于用户来说。我就是想全然关闭第三方程序,以免过多使用我的流量或者偷偷的做一些我不希望的操作。貌似没有办法去关闭,那为什么呢? 我这里先讲述当中一种情况。
Service顾名思义是服务。执行在前后台后都能够,即能够执行在当前进程也能够执行在其它的进程里,Service能够为多个APP共享使用,是通过binder机制来实现的。当我Kill掉一个带有服务的进程(没有调用stopService()), 过一会该应用会自己主动重新启动。以下是代码的调用顺序。自下往上查看。
com.android.server.am.ActiveServices.scheduleServiceRestartLocked(ActiveServices.java)
com.android.server.am.ActiveServices.killServicesLocked (ActiveServices.java)
com.android.server.am.ActivityManagerService.cleanUpApplicationRecordLocked(ActivityManagerService.java)
com.android.server.am.ActivityManagerService.handleAppDiedLocked(ActivityManagerService.java)
com.android.server.am.ActivityManagerService.appDiedLocked(ActivityManagerService.java)
com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied(ActivityManagerService.java)
从代码流程上我们看出该service被restart。进程也依据该service启动起来, service就执行在重新启动的进程里。
在这样的情况下是不是就真没办法了呢,当然不是。假设我们在service中覆盖onStartCommand这个函数而且返回值为START_NOT_STICKY,在我们kill该进程后则不会自己主动重新启动,我们想关闭的应用也能够全然关闭了。不会再自己主动重新启动了。
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
Framwork实现代码
frameworks/base/services/java/com/android/server/am/ActiveServices.java case Service.START_NOT_STICKY: {
// We are done with the associated start arguments.
r.findDeliveredStart(startId, true);
if (r.getLastStartId() == startId) {
// There is no more work, and this service
// doesn't want to hang around if killed.
r.stopIfKilled = true; // 该变量设置为true
}
break;
} if (sr.startRequested && (sr.stopIfKilled || canceled)) { //进入到该条件中
if (sr.pendingStarts.size() == 0) {
sr.startRequested = false;
if (sr.tracker != null) {
sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis());
}
if (!sr.hasAutoCreateConnections()) {
// Whoops, no reason to restart!
bringDownServiceLocked(sr); //运行在这里。不会重新启动App
}
}
}
重写onStartCommand方法且返回值为START_NOT_STICKY的代码调用顺序,自下而上查看。
com.android.server.am.ActiveServices.bringDownServiceLocked(ActiveServices.java)
com.android.server.am.ActiveServices.killServicesLocked(ActiveServices.java)
com.android.server.am.ActivityManagerService.cleanUpApplicationRecordLocked(ActivityManagerService.java)
com.android.server.am.ActivityManagerService.handleAppDiedLocked(ActivityManagerService.java)
com.android.server.am.ActivityManagerService.appDiedLocked(Activi tyManagerService.java)
com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied(ActivityManagerService.java)
附上Google doc 对于onStartCommand返回值的说明
For started services, there are two additional major modes of operation they can decide to run in, depending on the value they return from onStartCommand():START_STICKY
is used for services that are explicitly started and stopped as needed, whileSTART_NOT_STICKY
orSTART_REDELIVER_INTENT
are used for services that should only remain running while processing any commands sent to them. See the linked documentation for more detail on the semantics.
在这里对这个返回值做下解释:
当服务进程因某种原因(内存不够,强制关闭等)被kill掉时,START_STICKY再次,在系统中创建了后有足够的内存service, 在onStartCommand在handle它是null intent.
START_NOT_STICKY通知系统不会再次创建service. 另一种回报值START_REDELIVER_INTENT再创service而伴随着原intent围棋处理。
Android在第三方应用程序系统应用尽早开始,杀死自己主动的第三方应用程序,以重新启动的更多相关文章
- Android(java)学习笔记219:开发一个多界面的应用程序之两种意图
1.两种意图: (1)显式意图: 在代码里面用intent设置要开启Activity的字节码.class文件: (2)隐式意图: Android(java)学习笔记218:开发一个多界面的应用程序之人 ...
- Android系统--输入系统(十五)实战_使用GlobalKey一键启动程序
Android系统--输入系统(十五)实战_使用GlobalKey一键启动程序 1. 一键启动的过程 1.1 对于global key, 系统会根据global_keys.xml发送消息给某个组件 & ...
- Android(java)学习笔记162:开发一个多界面的应用程序之两种意图
1.两种意图: (1)显式意图: 在代码里面用intent设置要开启Activity的字节码.class文件: (2)隐式意图: Android(java)学习笔记218:开发一个多界面的应用程序之人 ...
- 关于如何在Android、Java等非微软平台上建立高信任的SharePoint应用程序
关于如何在非微软平台上建立高信任的SharePoint应用程序 原文 :http://blogs.msdn.com/b/kaevans/archive/2014/07/14/high-trust-sh ...
- Android 使用PLDroidPlayer播放网络视频 依据视频角度自己主动旋转
近期由于项目需求 .须要播放网络视频 .于是乎 研究了一番 ,说说我遇到的那些坑 如今市面上有几个比較主流好用的第三方框架 Vitamio ( 体积比較大,有商业化风险 github:https:// ...
- Android中如何像 360 一样优雅的杀死后台Service而不启动
http://my.oschina.net/mopidick/blog/277813 目录[-] 一.已知的 kill 后台应用程序的方法 方法: kill -9 pid 二.终极方法,杀死后台ser ...
- Android开发之 Windows环境下通过Eclipse创建的第一个安卓应用程序(图文详细步骤)
第一篇 windows环境下搭建创建的第一个安卓应用程序 为了方便,我这里只采用了一体包进行演示. 一.下载安卓环境的一体包. 官网下载:安卓官网(一般被墙了) 网盘下载: http://yunpa ...
- 【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面
大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要想实现应用程序只启动一次引导界面这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单, ...
- Android手机平板两不误,使用Fragment实现兼容手机和平板的程序
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8744943 记得我之前参与开发过一个华为的项目,要求程序可以支持好几种终端设备,其 ...
随机推荐
- 为什么android你用的越多,速度较慢的手机
依据第三方的调研数据显示,有 77% 的 Android 手机用户承认自己曾遭遇过手机变慢的影响,百度搜索"Android+ 卡慢",也有超过 460 万条结果. 在业内.Andr ...
- 十步完全理解SQL(转)
本文由 伯乐在线 - 水果泡腾片 翻译.未经许可,禁止转载!英文出处:Lukas Eder.欢迎加入翻译组. 很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同 ...
- 【读书札记】建立第一个Web项目
安装配置好jdk.tomcat,我用的版本号是7.0.54,我放在C:\server\apache-tomcat-7.0.54下, CATALINA_BASE:C:\server\apache-tom ...
- MVC Controller向View传值(ViewData与ViewBag)
近期在开发项目中,使用的是ASP.NET MVC因为之前并没有接触,对于它的传值方式有些陌生,在这里进行初步总结积累学习. 一:使用 ViewData使用: public ActionResult I ...
- 区间第K大
protected static int partitions(List<KDNode> data,int left,int right,int k,int pos){ int l = l ...
- 【转】Android Web Server
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://vaero.blog.51cto.com/4350852/1188602 Andr ...
- ubuntu中KDE与GNOME安装切换
转载:http://apps.hi.baidu.com/share/detail/18919303 1.在Ubuntu中安装KDE桌面命令 sudo apt-get install kUbuntu-d ...
- Recall(检出率)和 Precision(准确性)
这两个方面是模式识别和信息检索使用措施值. 浅显易懂的理解,用以下的图片和公式最好只是. 那么 - 召回率R:用检索到相关文档数作为分子.全部相关文档总数作为分母.即R = A / ( A + C ) ...
- 技术七Gitservergitolite要构建和操作方便
最近,人懒,为了让自己的变化,所以,我决定花时间学习一些新的技术,.对于这些新技术,现在的需求不是很高.只需要在它的入口. 由于本人仅仅是花三四天整出来的东西,所以不洗勿喷,另外难免会有错误,如有还请 ...
- jdk阅读xml文件
前言 你需要阅读的时间来写一个通用组件xml文件,但考虑到组件分布更容易,这样一来在第三方小引用jar包.因此,直接jdk内建的xml分析方法.可能都没有第三发的组件强大. 导入的文件: import ...