一、背景:项目中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后一定能重启。
分享到:
相关推荐
利用VS2010.net 及Mono for Android 开发Android应用程序, 创建应用程序,并打包生成可安装的apk文件。
利用c#和vs2010.net开发Android应用程序,连接SQL Server数据库进行数据操作 1、直接连接SQL Server 2、通过服务连接SQL Server
使用Mono for Android和.Net/C#开发Android 应用程序,环境搭建(开发环境配置和环境变量配置) 1、安装JDK 2、安装Android SDK 3、安装Visual Studio 2010及SP1补丁包(参见...
内存优化是Android应用程序开发中的关键环节,因为它直接影响到应用的性能、用户体验以及系统的稳定性。本文将深入探讨Android应用程序内存管理优化的相关知识点。 首先,我们理解内存优化的重要性。Android系统为...
Android系统的运行环境较为复杂,它需要支持各种类型的应用程序,同时还要保证用户体验的流畅性。这意味着Android必须能够在资源有限的情况下依然保持良好的性能。 **1.3.2. oom killer 在 android 中的不足** ...
该程序由TI公司开发,主要用于配置时钟芯片,时钟芯片类型有LMK04828、LMX2572、LMK05318、LMK04832等多种时钟芯片,其图形化界面方便了开发人员理解芯片结构,并将配置参数直接生成为十六进制数据,简单、方便。
本资源是关于LMK04828数据手册的知识点总结,涵盖了该芯片的特性、应用场景、技术参数等方面的信息。 LMK04828是一款超低噪声JESD204B兼容时钟抖动清洁器,具有双环PLL架构。该芯片可以提供高精度的时钟输出,满足...
LMK04906寄存器配置,晶振20MHz, AC耦合,VCO=2.4G(请注意VCO只能配置在2.37-2.7G之间,否则将不成功),产生多路时钟(120M,160M,100M等),在项目上已验证。
LMK04816管理上电时序的代码,C语言实现,已成功应用在工程电路板中,寄存器配置很清楚, 推荐参考
LMK04828-EP是一款高性能的时钟抖动清洁器,其采用JESD204B标准,适用于多种高频领域应用。LMK04828-EP支持多种应用,包括无线基础设施、数据转换器时钟、网络、医疗视频、军事航空以及测试测量等。 这款设备内置了...
Android系统架构可以概括为四层结构,分别是基于Linux的内核模块、运行时库和其他库、应用程序框架以及应用程序。 1. **基于Linux的内核模块**: Android内核基于Linux 2.6,它作为硬件层和软件层之间的抽象层,...
lmk04806 register definition
LMK00338芯片是一款高性能的时钟管理器,常用于通信、数据中心和工业应用中的时钟系统。在电子设计中,正确地布局和焊接芯片是至关重要的,这通常涉及到PCB(印制电路板)设计和焊盘配置。Allegro是一款由Cadence ...
1. 移动应用程序的性能优化:研究和了解Android操作系统的内存管理机制,可以帮助开发者更好地优化自己的应用程序,减少内存的使用和浪费,提高应用程序的性能和可靠性。 2. 内存问题解决:研究和了解Android操作...
旋入式液位计是一种用于测量液体或固体颗粒介质中液面高度的传感器。...无论是从技术参数,还是从实际应用的角度来看,LMK351都表现出色,并且能够在恶劣的工业环境中稳定运行,满足各种严格的应用需求。
由于压力式液位计具有结构简单、安装方便和成本较低等优点,被广泛应用于水处理、化工、食品、医药等行业。 知识点二:LMK358的技术参数和特点 LMK358液位计的技术参数主要包括量程、精度、信号输出等。量程范围从...
在应用方面,LMK 358/LMK 358H系列投入式液位计广泛适用于开放液罐的低液位监控、井或开放水域的深度或液位测量、地下水水位测量、给水和污水处理,以及化工和制药工业中需要长期稳定性监测的场合。其不锈钢的材质和...
LMK04821是一款高性能的时钟发生器,常用于通信系统、数据中心和工业应用等需要精确时钟信号的领域。这款芯片能够提供多种频率输出,且可以通过SPI(Serial Peripheral Interface)进行配置和控制,以适应不同的系统...
BD SENSORS LMK458H还符合本安防爆标准,适用于易爆环境中的应用,这增加了其在特定工业场合应用的安全性。根据设备的典型应用场景,如水处理、饮用水提取、海水淡化、造船和海上作业等,该液位计能够为各种工业提供...