一、背景:项目中APP需要常驻后台,但Android的LMK(low memory kill)会根据自己的算法在内存不足时清理一些进程。如何尽量不让LMK干掉自己的成呢?
二、调查:
参考一:http://bbs.csdn.net/topics/360088771#r_72861243
引用
Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用。当系统觉得当前的资源非常有限的时候,为了保 证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存。这样就能保证真正对用户有用的程序仍然再运行。如果你的 Service 碰上了这种情况,多半会先被杀掉。但如果你增加 Service 的优先级就能让他多留一会,我们可以用 setForeground(true) 来设置 Service 的优先级。
为什么是 foreground ? 默认启动的 Service 是被标记为 background,当前运行的 Activity 一般被标记为 foreground,也就是说你给 Service 设置了 foreground 那么他就和正在运行的 Activity 类似优先级得到了一定的提高。当让这并不能保证你得 Service 永远不被杀掉,只是提高了他的优先级。
有一个方法可以给你更清晰的演示,进入 $SDK/tools 运行命令
代码:
# adb shell dumpsys activity|grep oom_adj
Running Norm Proc # 6: oom_adj= 0 ProcessRecord{43635cf0 12689:com.roiding.netraffic/10028}
Running Norm Proc # 5: oom_adj= 7 ProcessRecord{436feda0 12729:com.android.browser/10006}
Running Norm Proc # 4: oom_adj= 8 ProcessRecord{4367e838 12761:android.process.acore/10016}
Running Norm Proc # 3: oom_adj= 8 ProcessRecord{43691cd8 12754:com.google.process.gapps/10000}
Running PERS Proc # 1: oom_adj=-12 ProcessRecord{43506750 5941:com.android.phone/1001}
Running PERS Proc # 0: oom_adj=-100 ProcessRecord{4348fde0 5908:system/1000}
返 回的一大堆东西,观察 oom_adj 的值,如果是大于 8 一般就是属于 backgroud 随时可能被干掉,数值越小证明优先级越高,被干掉的时间越晚。你看phone的程序是 -12 说明电话就是电话,其他什么都干了了,也的能接电话对吧。另外还有一个 -100 的,更邪乎因为是 system 如果他也完蛋了,你得系统也就挂了,嘿嘿。
参考二:http://www.cnblogs.com/perseus/archive/2012/01/11/2319660.html
引用
通过在androidmanifest.xml中的application标签中加入android:persistent="true" 属性后的确就能够达到保证该应用程序所在进程不会被LMK杀死。但有个前提就是应用程序必须是系统应用,也就是说应用程序不能采用通常的安装方式。必须将应用程序的apk包直接放到/system/app目录下。而且必须重启系统后才能生效。
除了一般的几种优先级外,还存在着coreserver,system这样的永远不会被LMK回收的优先级。系统中的电话应用就是coreserver优先级的。
通过查看源代码可以知道,只有应用程序的flag同时为FLAG_SYSTEM和FLAG_PERSISTENT时,才会被设置为coreserver优先级
if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
app.persistent = true;
app.maxAdj = CORE_SERVER_ADJ;
}
FLAG_SYSTEM在应用程序apk放在/system/app下时会被设置。所以才会出现只设置android:persistent="true"仍然会被杀死的情况。
测试时发现,将应用程序放到/system/app后不重启系统,仍然会被识别为普通的进程。当系统重新启动时,会在一开始就启动该进程并把它优先级设置为coreserver。
通过dumpsys activity命令能够很明显的看出其中差别。
Running processes (most recent first):
App # 3: adj= 2/1 ProcessRecord{30858c20 1877:com.android.email/10014} (started-services)
PERS # 2: adj=-100/0 ProcessRecord{308fb390 1713:system/1000} (fixed)
App # 1: adj= 0/0 ProcessRecord{30908198 1794:android.process.acore/10005} (top-activity)
PERS # 0: adj= -12/0 ProcessRecord{3090d488 1789:xiao.xiong.test/10026} (fixed)
而且adj=-12时,这个进程通过ddms手动stop后会立即启动
参考三:关于提高Android程序Service优先级的实践
http://gqdy365.iteye.com/admin/blogs/2148975
参考四:http://blog.sina.com.cn/s/blog_6f7ce0e60100viip.html
三、解决方案:
综上我们可以得到下面的结论:
1、给Application设置android:persistent="true"属性,要配合ApplicationInfo.FLAG_SYSTEM,所以说,只要预装的软件才可以;
2、APP中创建Service,并提搞Service的优先级,具体看我的文章:
关于提高Android程序Service优先级的实践
http://gqdy365.iteye.com/admin/blogs/2148975
3、在APP被kill掉之后怎么重启
方法一:在service的ondestroy中重启service;这种方法不可行,因为service被kill掉时根本不执行ondestroy方法;
方法二:onStartCommand(Intent,int,int)方法中更改flags为START_STICKY
引用
每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,这个方法return 一个int值,return 的值有四种:
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
分享到:
相关推荐
利用c#和vs2010.net开发Android应用程序,连接SQL Server数据库进行数据操作 1、直接连接SQL Server 2、通过服务连接SQL Server
利用VS2010.net 及Mono for Android 开发Android应用程序, 创建应用程序,并打包生成可安装的apk文件。
使用Mono for Android和.Net/C#开发Android 应用程序,环境搭建(开发环境配置和环境变量配置) 1、安装JDK 2、安装Android SDK 3、安装Visual Studio 2010及SP1补丁包(参见...
LMK04828数据手册
LMK04906寄存器配置,晶振20MHz, AC耦合,VCO=2.4G(请注意VCO只能配置在2.37-2.7G之间,否则将不成功),产生多路时钟(120M,160M,100M等),在项目上已验证。
LMK04816管理上电时序的代码,C语言实现,已成功应用在工程电路板中,寄存器配置很清楚, 推荐参考
该程序由TI公司开发,主要用于配置时钟芯片,时钟芯片类型有LMK04828、LMX2572、LMK05318、LMK04832等多种时钟芯片,其图形化界面方便了开发人员理解芯片结构,并将配置参数直接生成为十六进制数据,简单、方便。
lmk04806 register definition
lmk03806 芯片的开发以及应用,具体的介绍
lmk04828-ep.pdf
我们知道出现Crash应用闪退和崩溃一般有三个原因:ANR(程序无响应)、Exception(异常)、LMK(低内存杀死机制)。本文重点介绍LMK机制。 目的:了解LMK原理,探究进程保活的方案和程序异常处理的方法。 一、原理篇...
德国 BD SENSORS不锈钢投入式液位计LMK 358/LMK 358H 产品说明pdf,德国 BD SENSORS不锈钢投入式液位计LMK 358/LMK 358H 产品说明
一款lmk03806评估板的使用指南,ti官网
德国BD SENSORS 投入式液位计 LMK358产品样本pdf,德国BD SENSORS 投入式液位计 LMK358产品样本
德国-BD SENSORS 流体静力液位计LMK457产品说明pdf,德国-BD SENSORS 流体静力液位计LMK457产品说明
德国BD SENSORS 旋入式液位计 LMK351产品样本pdf,博德旋入式液位计LMK351 选型参数介绍
德国BD SENSORS 投入式液位计 LMK458H产品样本pdf,德国BD SENSORS 投入式液位计 LMK458H产品样本
德国 BD SENSORS 旋入式液位计 LMK 351产品说明rar,德国 BD SENSORS 旋入式液位计 LMK 351产品说明
德国 BD SENSORS 不锈钢投入式液位计 LMK 382/LMK 382 H 产品说明pdf,德国 BD SENSORS 不锈钢投入式液位计 LMK 382/LMK 382 H 产品说明
LMK04828和lmk04826编写指导书,来自TI官方说明