1、 Android不能杀进程:如何让Android程序在后台运行,不会像QQ一样被杀
方法:
对于一个服务,可以先设置为前台运行:
publicvoidMyService.onCreate(){
super.onCreate();
Notificationnotification=newNotification(_service_icon,
“my_service_name”,
System.currentTimeMillis());
PendingIntentp_intent=PendingIntent.getActivity (this,0,
newIntent(this,MyMainActivity.class),0);
notification.setLatestEventInfo(this,”MyServiceNotification,”MyServiceNotificationisRunning!”,p_intent);
Log.d(TAG,String .format(“notification=%s”,notification));
startForeground(,notification);//notificationID:,youcannameitasyouwill.Important settings—————— ————–
相对于/data/app下的应用,放在/system/app下的应用享有更多的特权,比如如果在它的Manifest.xml文件中如果persistent 属性设置为 true,可以防止内存不足杀手。例如应用’Phone’的AndroidManifest.xml文件:
android:persistent=”true”
android:label=”@string/dialerIconLabel”
android:icon=”@drawable/ic_launcher_phone”>
设置后app会升级到系统核心级别,无论如何都不会被杀掉,settings->app停止操作是在许可证中也被阻止。
设置前的日志:Proc#19:adj=svc/B:
#cat/proc//oom_adj
设置后的日志:PERS#19:adj=core/F:
#cat/ proc//oom_adj
-12#这是CORE_SERVER_ADJ
注意:init进程的oom_adj为-16(即SYSTEM_ADJ):cat/proc/1/oom_adj
Android相关部分分析:
在文件frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中有以下代码:
finalProcessRecordaddAppLocked(ApplicationInfoinfo){
ProcessRecordapp=getProcessRecordLocked(info.processName,info. uid );
if(app==null){
app=newProcessRecordLocked(null,info,null);
mProcessNames.put(info.processName,info.uid,app);
updateLruProcessLocked ( app,true,true);if((info.flags&(_PERSISTENT))
==(_PERSISTENT)){
app.persistent=true;
app.maxAdj=CORE_SERVER_ADJ;//这个常数值为-12、 if(app.thread==null&&mPersistentStartingProcesses.indexOf(app)<0){
mPersistentStartingProcesses.add(app);
startProcessLocked(app,”addedapplication”,app.processName);returnapp;可以看出如果要成为coreservice(即app.maxAdj=CORE_SERVER_ADJ(-12)),应用需要两个标志FLAG_SYSTEM和FLAG_PERSISTENT,FLAG_SYSTEM指的是位于/system/app下的应用,FLAG_PERSISTENT指的是持久化属性。
对于 frameworks/base/services/java/com/android/server/SystemServer.java,调用
ActivityManagerService.setSystemProcess();
将 app.maxAdj 设置为 SYSTEM_ADJ,即 -16 。 Android 中的进程是受管理的。当系统进程空间紧张时,进程会根据优先级自动回收。这就带来了三个问题:
1)回收规则:什么时候回收,哪一个回收?
2) 避免误杀:如何防止回收?
3) 数据恢复和保存:如果被回收了怎么办?
Android将进程分为6个级别,按优先级降序排列:
1、前台进程(FOREGROUND_APP)
2、可视化进程(VISIBLE_APP)
3、二级服务进程(SECONDARY_SERVER)
4.后台进程 (HIDDEN_APP)
5、内容提供者节点 (CONTENT_PROVIDER)
6、空进程(EMPTY_APP) 1、如果一个进程同时包含服务和可视活动,那么这个进程应该归属于可视进程,而不是服务进程。
2、此外,如果其他进程依赖于它,则可以提高一个进程的水平。例如,进程 A 中的服务绑定到进程 B 中的组件,进程 A 将始终被认为至少与进程 B 一样重要。
3、系统中的电话服务分为前台进程,而不是二级服务进程。
在android中,进程的oom_adj值也代表了它的优先级。 oom_adj 值越高,进程的优先级越低。在文件 /init.rc 中设置了以下属性:
setpropro.FOREGROUND_APP_ADJ0
setpropro.VISIBLE_APP_ADJ1
setpropro.SECONDARY_SERVER_ADJ2
setpropro.HIDDEN_APP_MIN_ADJ7
setpropro.CONTENT_PROVIDER_
setpropro.EMPTY_APP_
在/init.rc中,设置PID为1的进程(init进程)的oom_adj为SYSTEM_ADJ(-16):
#Setinititsforkedchildren’soom_adj.
write/proc/1/oom_adj-16
查看本地设置:
cat/sys/mole/lowmemorykiller/parameters/adj
0,1,2,7,14,15
回收时机:
文件/init.rc:
setpropro.FOREGROUND_APP_MEM//6M
setpropro.VISIBLE_APP_MEM//8M
setpropro.SECONDARY_SERVER_MEM//
setpropro.HIDDEN_APP_MEM//
setpropro.CONTENT_PROVIDER_MEM//22、4M
setpropro.EMPTY_APP_MEM//
这些数字也是对应的内存阈值。一旦低于此值,Android 开始按顺序关闭相应级别的进程。
请注意,这些数字的单位是页:1page=4kB。所以以上六个数字对应(MB):6,8,16,20,22,24、
查看当前内存阈值设置:
cat/sys/mole/lowmemorykiller/parameters/minfree
重置值(对应不同需求):
echo”,,,,, “> /sys/mole/lowmemorykiller/parameters/minfree
这样,“空进程”会在可用内存低于该值时被杀死,“内容供应节点”类会在可用内存不足时被杀死低于工艺。
具体回收在ActivityManagerService.java中的trimApplications()函数中实现:
1、先把已经卸载包的无用进程去掉;
2、根据进程当前状态,更新oom_adj值,然后进行如下操作:
1)移除没有activity运行的进程;
2) 如果AP已保存所有活动状态,则结束AP。
3、**,如果还有很多活动在运行,则删除那些活动状态已保存的活动。
更新oom_adj的值:
在ActivityManagerService.java文件的ComputeOomAdjLocked()中计算进程的oom_adj,例如:
if(app==TOP_APP){
//Thelastapponthelististheforegroundapp.
adj=FOREGROUND_APP_ADJ;
app.adjType=”top-activity”;Androidkernel中的lowmemorykiller
Android的LowMemoryKiller会根据需要(系统内存不足时)杀死进程释放其内存,源码在内核/驱动程序/杂项/lowmemorykiller.c。简单来说,就是找到最适合杀死的进程,从而释放它占用的内存。
最适合的进程是:
•oom_adj越大
•占用的物理内存越多
一旦进程被选中,内核会发送SIGKILL信号杀死它:
for_each_process(p){if(selected==NULL|、p->oomkilladj>selected->oomkilladj|、
(p->oomkilladj==selected->oomkilladj&&tasksize>selected_tasksize))selected=p;if(selected! =NULL) {
force_sig(SIGKILL,selected);查看LRU列表:adbshellmpsysactivity
activitydemo在前台时:
包含Service的进程优先级比较高,分为computeOomAdjLocked 中的两个类别:
staticfinalintMAX_SERVICE_INACTIVITY=30*60*;
if(now<(s.lastActivity+MAX_SERVICE_INACTIVITY)){
if(adj>SECONDARY_SERVER_ADJ){
adj=SECONDARY_SERVER_ADJ;
app.adjType=”started-services”;
app.hidden=false;if(adj>SECONDARY_SERVER_ADJ){
app.adjType=”started-bg-services”;不可能完全阻止进程从被杀死,我们可以通过一些操作使进程不太可能被杀死:
1)提高进程的优先级:
*后台操作是Service运行在前台的形式,因为一个进程运行一个服务比一个进程效率更高运行一个后台activity 级别高;
*按下返回键,使进程中的activity在后台运行而不是destroy,并且返回键需要重新加载(没有运行任何activity的进程会被杀死) first).
*取决于其他优先级高的进程;
2) 强制修改进程属性:
*在进程中设置:setPersistent(true);
*在Manifest文件中设置(如上)。
1、 Android不能杀进程:如何让Android程序在后台运行,不会像QQ一样被杀
方法:
对于一个服务,可以先设置为前台运行:
publicvoidMyService.onCreate(){
super.onCreate();
Notificationnotification=newNotification(_service_icon,
“my_service_name”,
System.currentTimeMillis());
PendingIntentp_intent=PendingIntent.getActivity (this,0,
newIntent(this,MyMainActivity.class),0);
notification.setLatestEventInfo(this,”MyServiceNotification,”MyServiceNotificationisRunning!”,p_intent);
Log.d(TAG,String .format(“notification=%s”,notification));
startForeground(,notification);//notificationID:,youcannameitasyouwill.Important settings—————— ————–
相对于/data/app下的应用,放在/system/app下的应用享有更多的特权,比如如果在它的Manifest.xml文件中如果persistent 属性设置为 true,可以防止内存不足杀手。例如应用’Phone’的AndroidManifest.xml文件:
android:persistent=”true”
android:label=”@string/dialerIconLabel”
android:icon=”@drawable/ic_launcher_phone”>
设置后app会升级到系统核心级别,无论如何都不会被杀掉,settings->app停止操作是在许可证中也被阻止。
设置前的日志:Proc#19:adj=svc/B:
#cat/proc//oom_adj
设置后的日志:PERS#19:adj=core/F:
#cat/ proc//oom_adj
-12#这是CORE_SERVER_ADJ
注意:init进程的oom_adj为-16(即SYSTEM_ADJ):cat/proc/1/oom_adj
Android相关部分分析:
在文件frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中有以下代码:
finalProcessRecordaddAppLocked(ApplicationInfoinfo){
ProcessRecordapp=getProcessRecordLocked(info.processName,info. uid );
if(app==null){
app=newProcessRecordLocked(null,info,null);
mProcessNames.put(info.processName,info.uid,app);
updateLruProcessLocked ( app,true,true);if((info.flags&(_PERSISTENT))
==(_PERSISTENT)){
app.persistent=true;
app.maxAdj=CORE_SERVER_ADJ;//这个常数值为-12、 if(app.thread==null&&mPersistentStartingProcesses.indexOf(app)<0){
mPersistentStartingProcesses.add(app);
startProcessLocked(app,”addedapplication”,app.processName);returnapp;可以看出如果要成为coreservice(即app.maxAdj=CORE_SERVER_ADJ(-12)),应用需要两个标志FLAG_SYSTEM和FLAG_PERSISTENT,FLAG_SYSTEM指的是位于/system/app下的应用,FLAG_PERSISTENT指的是持久化属性。
对于 frameworks/base/services/java/com/android/server/SystemServer.java,调用
ActivityManagerService.setSystemProcess();
将 app.maxAdj 设置为 SYSTEM_ADJ,即 -16 。 Android 中的进程是受管理的。当系统进程空间紧张时,进程会根据优先级自动回收。这就带来了三个问题:
1)回收规则:什么时候回收,哪一个回收?
2) 避免误杀:如何防止回收?
3) 数据恢复和保存:如果被回收了怎么办?
Android将进程分为6个级别,按优先级降序排列:
1、前台进程(FOREGROUND_APP)
2、可视化进程(VISIBLE_APP)
3、二级服务进程(SECONDARY_SERVER)
4.后台进程 (HIDDEN_APP)
5、内容提供者节点 (CONTENT_PROVIDER)
6、空进程(EMPTY_APP) 1、如果一个进程同时包含服务和可视活动,那么这个进程应该归属于可视进程,而不是服务进程。
2、此外,如果其他进程依赖于它,则可以提高一个进程的水平。例如,进程 A 中的服务绑定到进程 B 中的组件,进程 A 将始终被认为至少与进程 B 一样重要。
3、系统中的电话服务分为前台进程,而不是二级服务进程。
在android中,进程的oom_adj值也代表了它的优先级。 oom_adj 值越高,进程的优先级越低。在文件 /init.rc 中设置了以下属性:
setpropro.FOREGROUND_APP_ADJ0
setpropro.VISIBLE_APP_ADJ1
setpropro.SECONDARY_SERVER_ADJ2
setpropro.HIDDEN_APP_MIN_ADJ7
setpropro.CONTENT_PROVIDER_
setpropro.EMPTY_APP_
在/init.rc中,设置PID为1的进程(init进程)的oom_adj为SYSTEM_ADJ(-16):
#Setinititsforkedchildren’soom_adj.
write/proc/1/oom_adj-16
查看本地设置:
cat/sys/mole/lowmemorykiller/parameters/adj
0,1,2,7,14,15
回收时机:
文件/init.rc:
setpropro.FOREGROUND_APP_MEM//6M
setpropro.VISIBLE_APP_MEM//8M
setpropro.SECONDARY_SERVER_MEM//
setpropro.HIDDEN_APP_MEM//
setpropro.CONTENT_PROVIDER_MEM//22、4M
setpropro.EMPTY_APP_MEM//
这些数字也是对应的内存阈值。一旦低于此值,Android 开始按顺序关闭相应级别的进程。
请注意,这些数字的单位是页:1page=4kB。所以以上六个数字对应(MB):6,8,16,20,22,24、
查看当前内存阈值设置:
cat/sys/mole/lowmemorykiller/parameters/minfree
重置值(对应不同需求):
echo”,,,,, “> /sys/mole/lowmemorykiller/parameters/minfree
这样,“空进程”会在可用内存低于该值时被杀死,“内容供应节点”类会在可用内存不足时被杀死低于工艺。
具体回收在ActivityManagerService.java中的trimApplications()函数中实现:
1、先把已经卸载包的无用进程去掉;
2、根据进程当前状态,更新oom_adj值,然后进行如下操作:
1)移除没有activity运行的进程;
2) 如果AP已保存所有活动状态,则结束AP。
3、**,如果还有很多活动在运行,则删除那些活动状态已保存的活动。
更新oom_adj的值:
在ActivityManagerService.java文件的ComputeOomAdjLocked()中计算进程的oom_adj,例如:
if(app==TOP_APP){
//Thelastapponthelististheforegroundapp.
adj=FOREGROUND_APP_ADJ;
app.adjType=”top-activity”;Androidkernel中的lowmemorykiller
Android的LowMemoryKiller会根据需要(系统内存不足时)杀死进程释放其内存,源码在内核/驱动程序/杂项/lowmemorykiller.c。简单来说,就是找到最适合杀死的进程,从而释放它占用的内存。
最适合的进程是:
•oom_adj越大
•占用的物理内存越多
一旦进程被选中,内核会发送SIGKILL信号杀死它:
for_each_process(p){if(selected==NULL|、p->oomkilladj>selected->oomkilladj|、
(p->oomkilladj==selected->oomkilladj&&tasksize>selected_tasksize))selected=p;if(selected! =NULL) {
force_sig(SIGKILL,selected);查看LRU列表:adbshellmpsysactivity
activitydemo在前台时:
包含Service的进程优先级比较高,分为computeOomAdjLocked 中的两个类别:
staticfinalintMAX_SERVICE_INACTIVITY=30*60*;
if(now<(s.lastActivity+MAX_SERVICE_INACTIVITY)){
if(adj>SECONDARY_SERVER_ADJ){
adj=SECONDARY_SERVER_ADJ;
app.adjType=”started-services”;
app.hidden=false;if(adj>SECONDARY_SERVER_ADJ){
app.adjType=”started-bg-services”;不可能完全阻止进程从被杀死,我们可以通过一些操作使进程不太可能被杀死:
1)提高进程的优先级:
*后台操作是Service运行在前台的形式,因为一个进程运行一个服务比一个进程效率更高运行一个后台activity 级别高;
*按下返回键,使进程中的activity在后台运行而不是destroy,并且返回键需要重新加载(没有运行任何activity的进程会被杀死) first).
*取决于其他优先级高的进程;
2) 强制修改进程属性:
*在进程中设置:setPersistent(true);
*在Manifest文件中设置(如上)。
产品猿社区致力收录更多优质的商业产品,给服务商以及软件采购客户提供更多优质的软件产品,帮助开发者变现来实现多方共赢;
日常运营的过程中我们难免会遇到各种版权纠纷等问题,如果您在社区内发现有您的产品未经您授权而被用户提供下载或使用,您可按照我们投诉流程处理,点我投诉;
本文来自用户发布投稿,不代表产品猿立场 ;若对此文有疑问或内容有严重错误,可联系平台客服反馈;
部分产品是用户投稿,可能本文没有提供官方下下载地址或教程,若您看到的内容没有下载入口,您可以在我们产品园商城搜索看开发者是否有发布商品;若您是开发者,也诚邀您入驻商城平台发布的产品,地址:点我进入;
如若转载,请注明出处:https://www.chanpinyuan.cn/33149.html;