引用
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之后会立即启动
参考3:关于改进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以后一定能重启。