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在第三方应用程序系统应用尽早开始,杀死自己主动的第三方应用程序,以重新启动的更多相关文章

  1. Android(java)学习笔记219:开发一个多界面的应用程序之两种意图

    1.两种意图: (1)显式意图: 在代码里面用intent设置要开启Activity的字节码.class文件: (2)隐式意图: Android(java)学习笔记218:开发一个多界面的应用程序之人 ...

  2. Android系统--输入系统(十五)实战_使用GlobalKey一键启动程序

    Android系统--输入系统(十五)实战_使用GlobalKey一键启动程序 1. 一键启动的过程 1.1 对于global key, 系统会根据global_keys.xml发送消息给某个组件 & ...

  3. Android(java)学习笔记162:开发一个多界面的应用程序之两种意图

    1.两种意图: (1)显式意图: 在代码里面用intent设置要开启Activity的字节码.class文件: (2)隐式意图: Android(java)学习笔记218:开发一个多界面的应用程序之人 ...

  4. 关于如何在Android、Java等非微软平台上建立高信任的SharePoint应用程序

    关于如何在非微软平台上建立高信任的SharePoint应用程序 原文 :http://blogs.msdn.com/b/kaevans/archive/2014/07/14/high-trust-sh ...

  5. Android 使用PLDroidPlayer播放网络视频 依据视频角度自己主动旋转

    近期由于项目需求 .须要播放网络视频 .于是乎 研究了一番 ,说说我遇到的那些坑 如今市面上有几个比較主流好用的第三方框架 Vitamio ( 体积比較大,有商业化风险 github:https:// ...

  6. Android中如何像 360 一样优雅的杀死后台Service而不启动

    http://my.oschina.net/mopidick/blog/277813 目录[-] 一.已知的 kill 后台应用程序的方法 方法: kill -9 pid 二.终极方法,杀死后台ser ...

  7. Android开发之 Windows环境下通过Eclipse创建的第一个安卓应用程序(图文详细步骤)

    第一篇  windows环境下搭建创建的第一个安卓应用程序 为了方便,我这里只采用了一体包进行演示. 一.下载安卓环境的一体包. 官网下载:安卓官网(一般被墙了) 网盘下载: http://yunpa ...

  8. 【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面

    大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要想实现应用程序只启动一次引导界面这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单, ...

  9. Android手机平板两不误,使用Fragment实现兼容手机和平板的程序

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8744943 记得我之前参与开发过一个华为的项目,要求程序可以支持好几种终端设备,其 ...

随机推荐

  1. iOS 获取联系人,并调用系统地址簿UI

    1.加入 AddressBook库 推断授权状态 -(bool)checkAddressBookAuthorizationStatus { //取得授权状态 ABAuthorizationStatus ...

  2. sql 与linq的转换

    1. left Join 原始sql select t.[MINTAccountIdentifier] from BSS_Tenant t left join BL_SAPCustomer s on ...

  3. JAVA编程思想(2) - 操作符(一)

    "在最底层,Java中的数据是通过操作符来操作的." 1. 使用Java操作符 -操作符接受一个或者多个參数,并生成一个新值,參数的形式与普通的方法调用不用,但效果是同样的.加号和 ...

  4. WebCollector 2.x 新手教程

    WebCollector爬虫官网:https://github.com/CrawlScript/WebCollector 技术讨论群:250108697 WebCollector 2.x教程列表 We ...

  5. 切割图像(五)主动轮廓模型Snake简要模型

    切割图像(五)主动轮廓模型Snake简要模型 zouxy09@qq.com http://blog.csdn.net/zouxy09 在"图像切割之(一)概述"中咱们简单了解了眼下 ...

  6. 《数字图像处理原理与实践(MATLAB文本)》书代码Part7

    这篇文章是<数字图像处理原理与实践(MATLAB文本)>一本书的代码系列Part7(由于调整先前宣布订单,请读者注意分页程序,而不仅仅是基于标题数的一系列文章),第一本书特色186经225 ...

  7. AND信号灯和信号灯集-----同步和互斥解决面向对象(两)

    AND信号 互斥的上述处理,它是针对仅在进程之间共享的一个关键资源方面.在一些应用.这是一个过程,需要在为了自己的使命后,获得两个或多个其他共享资源运行. 个进程A和B.他们都要求訪问共享数据D和E. ...

  8. unity3d简单的相机跟随及视野旋转缩放

    1.实现相机跟随主角运动 一种简单的方法是把Camera直接拖到Player下面作为Player的子物体,另一种方法是取得Camera与Player的偏移向量,并据此设置Camera位置,便能实现简单 ...

  9. mysql 多个字段拼接

    Mysql的查询结果行字段拼接,能够用以下两个函数实现: 1. concat函数 mysql> select concat('1','2','3') from test ; +--------- ...

  10. BZOJ 2431 HAOI2009 在列的数目的顺序相反 递归

    标题效果:乞讨1~n有都布置在物种的数目相反的顺序k计划数 订购f[i][j]对于前者i原子的反向排列的数j计划数 因此,我们将第一i插入的数1~i-1该装置 能生产0~i-1反向对 再就是 f[i] ...