当前位置:首页 » 安卓系统 » android进程被回收

android进程被回收

发布时间: 2022-11-25 11:52:47

Ⅰ Android进程级别与如何防止服务进程被回收

一般情况下系统进程强制停止后很快又会自动开启,系统蓝牙也一样,除非你真的不想用蓝牙,就把它卸载了,可以用qq手机管家里的软件管理功能,卸载系统部件后它可以在回收站装回来,当然卸载系统软件前提要root。。。

Ⅱ android service 什么情况下会被系统回收

android service 开机启动后被被自动关闭掉原因:
Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用。当系统觉得当前的资源非常有限的时候,为了保 证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存。这样就能保证真正对用户有用的程序仍然再运行。如果你的 Service 碰上了这种情况,多半会先被杀掉。但如果你增加 Service 的优先级就能让他多留一会,我们可以用 setForeground(true) 来设置 Service 的优先级。
默认启动的 Service 是被标记为 background,当前运行的 Activity 一般被标记为 foreground,也就是说你给 Service 设置了 foreground 那么他就和正在运行的 Activity 类似优先级得到了一定的提高。当让这并不能保证你得 Service 永远不被杀掉,只是提高了他的优先级。

Ⅲ 如何判断 android被 系统回收

我觉得没有显式的判断方法。
Activity就像Java中的一个类,类可以实例化出很多个对象,但你无法判断该类所有的对象是否已经被内存回收了。
android中显式的调用finish()方法,或者隐身的(比如按“Back”键导致该activity被finish()掉),会导致该activity被回收。

Ⅳ 为什么 12G 内存的 Android 手机依旧会被杀后台

不知不觉间 Android 陷入了一个关于“后台”的怪圈:一边各大厂商陆续推出了 12G RAM 的手机,另一边你刚刚放到后台的下载任务没有如预期那样后台挂机下载,打开微信发现还得陪启动画面的孤独小人共赏蓝色星球、按照教程辛辛苦苦做了半个小时的 Tasker 规则、却没有按照计划自动执行……

于是一个耳熟能详的句子开始在我们脑海中成型—— 我的后台又被“杀”了

应用开发者的“控诉”

遇到上述问题的人不止你一个,很多人选择向这些应用的开发者反馈问题,殊不知问题其实不在应用本身。

Android 平台着名睡眠追踪应用 Sleep as Android 的开发团队 Urbandroid Team 不堪其扰,索性上线了一个名为“别‘杀’我应用”的网站,矛头直指手机厂商糟糕的后台管理机制。

以三星为例,Urbandroid Team 称,三星的部分机型在升级到基于 Android 9 的 One UI 后“杀后台”现象变得尤为严重,自适应电池(Adaptive Battery)机制相比原生 Android 变得尤为激进,3 天内没有启动过的应用甚至无法从后台再次启动。最为糟糕的情况是,如果你安装了一个可以自动跳过周末的第三方闹钟,那这个闹钟应用很有可能不会像系统闹钟那样在下周一早上准时响起……

正如“别‘杀’我应用”网站上控诉的那样,拥有类似机制的还包括华为、一加、小米、华硕等等手机厂商的定制版 Android 系统,它们管理后台的方式大同小异,但都秉承着 iOS 上那一套“划掉就杀掉”的原则——当我们把某款应用的任务卡片从多任务界面划去,它们也就彻底从手机后台中抹除掉了。

这里你可能会问很多问题:

我们得从一些基础的原理说起。

Android 的内存回收机制

在 官方文档 中,Google 将“不受应用自身直接控制的应用进程生命周期”描述为 Android 最为基础也最为独特的核心特性,这里我们不妨将“应用进程生命周期”暂时理解为文章开头和第一部分所说的“后台”或“后台进程(process)”。

所以 Android 应用的后台进程去留本应是由 Android 系统来决定的

当可用运行内存空间不足时,Android 系统会自行决定对特定应用后台进程占用的空间进行回收释放,这个过程中 Android 挥舞着的那把大刀,叫做 LMK(Low Memory Killer)。那 LMK 又是如何判断哪些应用可以被“杀”掉、哪些应用又该暂时放过的呢?

每个应用都有各种各样的组成部分,其中特定组件的运行状态共同组成了一套供 LMK 进行内存回收的“优先级”参考,包括:前台进程、可见进程、服务进程和缓存进程。

前台进程、可见进程和服务进程往往与我们正在手机上执行的操作直接或间接相关 ,比如正在前台供我们交互和操作的活动窗口(Activity)、正在通过广播接收器(BroadcastReceiver)等待触发的 Tasker 规则、正在后台通过 Wi-Fi 网络自动上传备份照片的 Google Photos 以及前面提到的有待触发的闹钟等等。这些进程优先级从高到低依次递减,LMK 一般不会触及。

缓存进程则是那些暂时放在运行内存中的部分,也是和本文探讨话题主要相关的重点

只有在极端情况下 ,比如 Android 系统在回收掉所有缓存进程后发现空闲内存依然不够用(比如在低内存的“老爷机”上运行《崩坏 3》),这时 LMK 才会根据优先级继续对服务进程、可见进程和前台进程采取回收策略。 而当这些我们在正常使用中能够直观感受到的进程都不得不被被回收时 ,文章开头提到的微信重载、音乐中断、下载消失等等现象也就出现了。

谁动了你的后台

在可用内存充裕的情况下遭遇“杀后台”现象,一方面可能是 LMK 这把“大刀”出了问题(常见于 Android 9 时期的 Pixel 3 用户),另一方面则有可能是其它规则额外干预了 Android 系统正常的内存回收机制。

这里提到的“其它规则”主要有两种形式,一种类似部分华为设备上预装的“省电精灵”,它会将所有没有加入后台白名单中的应用后台统统清除,另一种则依托于 Google 推出的 后台检查 后台限制 自适应电池 等功能进行“魔改”,让这些功能的实际效果远超预期,甚至达到意料之外的负面效果。

根据 Don't kill my app! 的统计,第二种后台干预机制在三星、一加和早期的诺基亚机型中常见,这里厂商们通常会用到一种类似“白名单”的方法来进行过滤。

以三星手机基于 Android 9 的 One UI 为例,除了微信、QQ 等国内常见应用,One UI 默认会为所有第三方应用关闭“允许后台活动”这一选项,同时开启“优化电池使用量”这一功能。

部分搭载氢 OS 的一加机型则将上面提到的应用进程进行拆分,除了基于原生 Android 的后台限制、电池优化,还有一套名为“自启动管理”的设置来对应用的自启动进行管理以及一套名为“深度优化”的电池优化机制,后者会造成很多智能手表、手环设备在一段时间后丢失与手机的蓝牙连接,最终导致睡眠追踪、运动记录等等功能的失效。

问题在于上述功能埋藏较深,一般用户在安装应用后往往不会第一时间前往设置,一加的氢 OS 更是以系统更新之后自动重置部分用户设置闻名,那些需要在后台正常工作的应用,因此也被都被直接扔进了原生 Android 中用来限制“毒瘤”应用的“黑箱”里。

换句话说,国内大部分定制 ROM 在后台管理这件事情上都选择采用一种“ 宁肯错杀一千不肯放过一个 ”的做法。

关联阅读: 控制频繁启动的“毒瘤”,Android 9.0 用这些方法让你的手机更省电

多任务管理还是后台管理?

从某种程度上来说,国产手机厂商在 Android 后台管理上的做法虽然偏激,但它们都是国内特殊生态下的产物 。

一方面,尽管 Google 为 Android 设想了一套非常理想化的应用运行与后台管理机制 ,但大多数于原生 Android 中行之有效的后台管理机制在国内似乎都会变成“鸡肋”。

如果 Google 有 100 种提升 Android 应用运行效率,保证后台绿色、纯净的方法,国内毒瘤应用开发商就有 101 种绕过这些限制的方法。

借助共用的第三方推送服务实现链式唤醒、借助透明的悬浮窗保证后台存活、通过不断获取定位的方式来避免进程被系统回收……不管是出于实现消息推送这样单纯的目的还是为了不断唤醒用户设备以实现 KPI 目标这种下作的行为,在国内 Android 生态中均有出现。

虽然国内外的具体环境有所不同,但这类设计不规范的 Android 应用带来的问题却是一样的,这类应用放在后台不仅不会为我们带来便利,反而还会因为频繁唤醒设备带来不小的耗电问题。待机续航问题作为悬在国产 Android 机头顶的几把利剑之一,手机厂商不得不各自从系统层面推出自家的应对机制——这就有了上面提到的各种偏激式的后台管理方法。

另一方面,这里还涉及到一个非常重要的概念区分 :多任务管理和后台管理究竟是不是一回事?

国内 Android 生态由于早期受 iOS 影响较深,无论是开发商还是用户都更倾向于把“将应用卡片从多任务列表里划掉”的行为理解为清除对应用的后台进程。在上面提到的特殊生态环境的影响之下,这里被清除的后台进程往往又包括那些用于保证应用后台运行的可见进程、服务进程乃至前台进程在内。

在酷安应用市场,甚至还有得以在原生 Android 上实现类似“划掉卡片即停止运行”效果的应用,iOS 的后台管理理念在国内有多么深入人心可见一斑。

但这种后台管理理念却与 Google 对 Android 的多任务管理设计方式相悖。Google 一直以来都将 Android 手机上呼出任务卡片的那个界面叫做 Recents,最近几个版本的 Android 系统更是将其本地化为“概览”。结合 Google 在 Android 9 和 Android 10 手势交互上的变革,注重多任务管理而非后台管理的意图也越发明显。

当最近运行的应用以一张张卡片的形式呈现在我们面前时,Google 想要呈现的是一个能够让我们在不同任务间快速切换的多任务交互,而在理想状态下,后台管理则是交由系统处理、完全不应被用户感知的。

至于如何理性看待 Android 平台的后台管理,这里我们不妨借用绿色守护开发者 @OasisFeng 在“Android 多任务界面的划除交互”这个话题上的 答疑 来回答这个问题:

换句话说, 今后绝大部分需要在海外市场搭载 Google 服务上市的手机都必须满足这个要求

小结

就在上周三(9 月 25 日),酝酿已久的安卓统一推送联盟正式宣布收到华为、OPPO、一加和 realme 四家公司的进度确认,虽然 Google 的缺席也让国内 Android 生态也变得异常复杂,但国内 Android 设备也能用上的统一推送服务也算是终于迈出了具有实际意义的第一步。

只是距离转变人们对 Android“杀后台”这件事的看法依然还有很长的路要走。事实上,国内早在四五年前就出现过一次对“Android 需不需要‘杀后台’”问题的科普,但收效甚微,盲从 iOS 设计风格和交互逻辑国内 Android 厂商要负很大一部分责任。

希望靠谱、省电的统一推送系统能成为改观的第一步,也希望 @OasisFeng 口中那个甚至可以跨越设备重启恢复“后台状态”的理想化生态早日到来——至于当下,我们依然只能见招拆招,遇到应用无法正常执行后台任务时打开手机设置仔细翻找、设置,把它们扔进白名单或是给它们的后台卡片套个“锁”……

下载、安装了一款非白名单应用,该如何确保它不被“杀后台”呢?欢迎在评论区把你的设置方法分享给大家。

Ⅳ Android 如何进行进程保活

每一个 Android 应用启动后至少对应一个进程,有的是多个进程,而且主流应用中多个

进程的应用比例较大

对于任何一个进程,我们都可以通过 adb shell ps|grep <package_name>的方式来查看

它的基本信息

Android 中的进程跟封建社会一样,分了三流九等,Android 系统把进程的划为了如下

几种(重要性从高到低),网上多位大神都详细总结过(备注:严格来说是划分了 6 种)。

场景:

1.某个进程持有一个正在与用户交互的 Activity 并且该 Activity 正处于 resume 的

状态。

2.某个进程持有一个 Service,并且该 Service 与用户正在交互的 Activity 绑定。

3.某个进程持有一个 Service,并且该 Service 调用 startForeground()方法使之位于前台运行。

4.某个进程持有一个 Service,并且该 Service 正在执行它的某个生命周期回调方法,比如 onCreate()、 onStart()或 onDestroy()。

5.某个进程持有一个 BroadcastReceiver,并且该 BroadcastReceiver 正在执行其onReceive()方法。用户正在使用的程序,一般系统是不会杀死前台进程的,除非用户强制停止应用或者系统内存不足等极端情况会杀死。

场景:

1.拥有不在前台、但仍对用户可见的 Activity(已调用 onPause())。

2.拥有绑定到可见(或前台)Activity 的 Service

用户正在使用,看得到,但是摸不着,没有覆盖到整个屏幕,只有屏幕的一部分可见进程

不包含任何前台组件,一般系统也是不会杀死可见进程的,除非要在资源吃紧的情况下,

要保持某个或多个前台进程存活

场景

1.某个进程中运行着一个 Service 且该 Service 是通过 startService()启动的,与用户看见的界面没有直接关联。

在内存不足以维持所有前台进程和可见进程同时运行的情况下,服务进程会被杀死

场景:

在用户按了"back"或者"home"后,程序本身看不到了,但是其实还在运行的程序,

比如 Activity 调用了 onPause 方法系统可能随时终止它们,回收内存

场景:

某个进程不包含任何活跃的组件时该进程就会被置为空进程,完全没用,杀了它只有好处没坏处,第一个干它!

上面是进程的分类,进程是怎么被杀的呢?系统出于体验和性能上的考虑,app 在退到

后台时系统并不会真正的 kill 掉这个进程,而是将其缓存起来。打开的应用越多,后台缓存的进程也越多。在系统内存不足的情况下,系统开始依据自身的一套进程回收机制

来判断要 kill 掉哪些进程,以腾出内存来供给需要的 app, 这套杀进程回收内存的机制

就叫 Low Memory Killer。那这个不足怎么来规定呢,那就是内存阈值,我们可以使用

cat /sys/mole/lowmemorykiller/parameters/minfree 来查看某个手机的内存阈值。

其实系统在进程回收跟内存回收类似也是有一套严格的策略,可以

自己去了解,大概是这个样子的,oom_adj 越大,占用物理内存越多会被最先 kill 掉,OK,那么现在对于进程如何保活这个问题就转化成,如何降低 oom_adj 的值,以及如

何使得我们应用占的内存最少。

据说这个是手 Q 的进程保活方案,基本思想,系统一般是不会杀死前台进程的。所以要

使得进程常驻,我们只需要在锁屏的时候在本进程开启一个 Activity,为了欺骗用户,

让这个 Activity 的大小是 1 像素,并且透明无切换动画,在开屏幕的时候,把这个 Activity

关闭掉,所以这个就需要监听系统锁屏广播,我试过了,的确好使,如下。

如果直接启动一个 Activity,当我们按下 back 键返回桌面的时候,oom_adj 的值是 8,

上面已经提到过,这个进程在资源不够的情况下是容易被回收的。现在造一个一个像素

的 Activity。

为了做的更隐藏,最好设置一下这个 Activity 的主题,当然也无所谓了

在屏幕关闭的时候把 LiveActivity 启动起来,在开屏的时候把 LiveActivity 关闭掉,所以

要监听系统锁屏广播,以接口的形式通知 MainActivity 启动或者关闭 LiveActivity。

现在 MainActivity 改成如下

按下 back 之后,进行锁屏,现在测试一下 oom_adj 的值

果然将进程的优先级提高了。

但是还有一个问题,内存也是一个考虑的因素,内存越多会被最先 kill 掉,所以把上面

的业务逻辑放到 Service 中,而 Service 是在另外一个 进程中,在 MainActivity 开启这

个服务就行了,这样这个进程就更加的轻量,

OK,通过上面的操作,我们的应用就始终和前台进程是一样的优先级了,为了省电,

系统检测到锁屏事件后一段时间内会杀死后台进程,如果采取这种方案,就可以避免了

这个问题。但是还是有被杀掉的可能,所以我们还需要做双进程守护,关于双进程守护,

比较适合的就是 aidl 的那种方式,但是这个不是完全的靠谱,原理是 A 进程死的时候,

B 还在活着,B 可以将 A 进程拉起来,反之,B 进程死的时候,A 还活着,A 可以将 B

拉起来。所以双进程守护的前提是,系统杀进程只能一个个的去杀,如果一次性杀两个,

这种方法也是不 OK 的。

事实上

那么我们先来看看 Android5.0 以下的源码,ActivityManagerService 是如何关闭在应用

退出后清理内存的

在应用退出后,ActivityManagerService 不仅把主进程给杀死,另外把主进程所属的进

程组一并杀死,这样一来,由于子进程和主进程在同一进程组,子进程在做的事情,也

就停止了。所以在 Android5.0 以后的手机应用在进程被杀死后,要采用其他方案。

这种大部分人都了解,据说这个微信也用过的进程保活方案,移步微信 Android 客户端

后台保活经验分享,这方案实际利用了 Android 前台 service 的漏洞。

原理如下

对于 API level < 18 :调用 startForeground(ID, new Notification()),发送空的

Notification ,图标则不会显示。

对于 API level >= 18:在需要提优先级的 service A 启动一个 InnerService,两个服务

同时 startForeground,且绑定同样的 ID。Stop 掉 InnerService ,这样通知栏图标即

被移除。

public class KeepLiveService extends Service{

public static final int NOTIFICATION_ID=0x11; 

public KeepLiveService() {

}

@Override

public IBinder onBind(Intent intent){

throw new UnsupportedOperationException("Not yet implemented");

 }

 @Override 

public void onCreate() {

 super.onCreate(); //API 18 以下,直 接发 送 Notification 并 将 其 置 为 前 台

if(Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN_MR2){

startForeground(NOTIFICATION_ID,new Notification()); 

} else { //API 18 以上,发送 Notification 并将其置为前台后,启动 InnerService

Notification.Builder builder=new Notification.Builder(this);

builder.setSmallIcon(R.mipmap.ic_launcher);

startForeground(NOTIFICATION_ID, builder.build());

 startService(new Intent(this, InnerService.class));

 }

 }

 public class InnerService extends Service{

 @Override public IBinder onBind(Intent intent) {

 return null;

 } 

@Override public void onCreate() {

 super.onCreate(); //发送与 KeepLiveService中 ID 相同的 Notification,然后将其取消并取消自己的前台显示

 Notification.Builder builder = new Notification.Builder(this);

builder.setSmallIcon(R.mipmap.ic_launcher);startForeground(NOTIFICATION_ID,

builder.build());

new Handler().postDelayed(new Runnable() { 

@Override public void run() { 

stopForeground(true);

 NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

manager.cancel(NOTIFICATION_ID); 

stopSelf();

 }

 },

100);

 }

 }

 }

在没有采取前台服务之前,启动应用,oom_adj 值是 0,按下返回键之后,变成 9(不

同 ROM 可能不一样)

相互唤醒的意思就是,假如你手机里装了支付宝、淘宝、天猫、UC 等阿里系的 app,

那么你打开任意一个阿里系的 app 后,有可能就顺便把其他阿里系的 app 给唤醒了。

这个完全有可能的。此外,开机,网络切换、拍照、拍视频时候,利用系统产生的广播

也能唤醒 app,不过 Android N 已经将这三种广播取消了。

如果应用想保活,要是 QQ,微信愿意救你也行,有多少手机上没有 QQ,微信呢?或

者像友盟,信鸽这种推送 SDK,也存在唤醒 app 的功能。

拉活方法

JobSheler是作为进程死后复活的一种手段,

native进程方式最大缺点是费电,Native

进程费电的原因是感知主进程是否存活有两种实现方式,在 Native 进程中通过死循环

或定时器,轮训判断主进程是否存活,当主进程不存活时进行拉活。其次 5.0 以上系统

不支持。 但是 JobSheler 可以替代在 Android5.0 以上 native 进程方式,这种方式即

使用户强制关闭,也能被拉起来,亲测可行。

JobSheler@TargetApi(Build.VERSION_CODES.LOLLIPOP) 

public class MyJobService extends JobService {

 @Override

 public void onCreate() {

 super.onCreate();

 startJobSheler();

 }

public void startJobSheler() { 

try {

 JobInfo.Builder builder = new JobInfo.Builder(1,new ComponentName(getPackageName(), MyJobService.class.getName()));

builder.setPeriodic(5); builder.setPersisted(true); JobScheler jobScheler =(JobScheler)

this.getSystemService(Context.JOB_SCHEDULER_SERVICE);

jobScheler.schele(builder.build());

}

catch

(Exception ex)

{ ex.printStackTrace(); } }

 @Override 

public boolean onStartJob(JobParameters jobParameters) {

 return false; 

} @Override public boolean onStopJob(JobParameters jobParameters) { 

return false; 

}

 }

这个是系统自带的,onStartCommand 方法必须具有一个整形的返回值,这个整形的返

回值用来告诉系统在服务启动完毕后,如果被 Kill,系统将如何操作,这种方案虽然可

以,但是在某些情况 or 某些定制 ROM 上可能失效,我认为可以多做一种保保守方案。

1.START_STICKY

如果系统在 onStartCommand 返回后被销毁,系统将会重新创建服务并依次调用

onCreate 和 onStartCommand(注意:根据测试 Android2.3.3 以下版本只会调用

onCreate 根本不会调用 onStartCommand,Android4.0 可以办到),这种相当于服务

又重新启动恢复到之前的状态了)。

2.START_NOT_STICKY

如果系统在 onStartCommand 返回后被销毁,如果返回该值,则在执行完

onStartCommand 方法后如果 Service 被杀掉系统将不会重启该服务

3.START_REDELIVER_INTENT

START_STICKY 的兼容版本,不同的是其不保证服务被杀后一定能重启。

4.相比与粘性服务与系统服务捆绑更厉害一点,这个来自爱哥的研究,这里说的系统服务

很好理解,比如 NotificationListenerService,NotificationListenerService 就是一个监听

通知的服务,只要手机收到了通知,NotificationListenerService 都能监听到,即时用户

把进程杀死,也能重启,所以说要是把这个服务放到我们的进程之中,那么就可以呵呵



所以你的应用要是有消息推送的话,那么可以用这种方式去欺骗用户。

Ⅵ 如何防止android应用中的service被系统回收

永不被kill是不可能的,android系统应用都有可能会被kill,不要说用户应用了,只能说被kill以后还能重新启动。
Android中,当Service被kill后,如果重启需要使用BroadcastReceiver来实现,即广播接收者,例如利用BroadcastReceiver注册网络广播或者开关机广播,当接收到广播后直接启动service,这样就可以保证service被kill后,自动启动。
实现代码:
1.在配置文件AndroidManifest.xml中向系统注册BroadcastReceiver
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>

2.需要添加相应权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

3.在Receiver中就可以添加开机,或者网络状态改变后需要进行的操作
public class BootCompletedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

}
}
4.执行操作,Intent intent = new Intent(context,Service.class); context.startService(intent); 这样即可开机,或者网络状态改变后启动Service了。

Ⅶ Android应用程序被系统回收后处理

在android中如果一个应用程序被按Home键回到桌面了,这个时候应用程序就处于后台运行状态,后台运行状态的应用在系统内存不足的情况下有可能会被系统回收掉。我们可以用Android DDMS模拟一下把进程kill掉。然后重新进入应用的重启情况。

这个是app从启动-退出后台-系统kill-重启的一个流程

Ⅷ android应用被强杀或应用被回收导致的空指针问题等其他问题

在开发中我们经常会遇见app退到后台再打开会出现空指针、页面显示不全等一系列奇怪的问题。

当我们的进程被强杀或者被回收的时候,Android系统虽然让你的进程没有了,但是此进程中Activity中栈的信息还是存在的,也就是说此时当你点开此应用的时候程序中的Activity栈信息任然存在,只不过Activity中的数据都没有了,需要重新创建新的Activity数据。

分别涉及到:一个单例ConstantInstance 基类BaseAcyivity 首页MainActivity 启动页IndexActivity

Ⅸ 如何防止 android service被回收

众所周知, Service是跑后台的. 但是有些Rom厂商把一键清理做的真是太好用了, 以至于一键清理变成了一种习惯, Service已经变的不再是Service了. 那为什么像诸如360, 微信, QQ...却可以傍山傍水.哦, 用错词了. 大家懂的. .
言归正传, android的系统进程分为五个等级, Foreground Process(前台进程), Visible Process(可见进程), Service Process(服务进程), Background Process(后台进程), Empty Process(空进程), Service的进程处于第三个位置. 系统的回收会从低到高依次回收, 所以我们必须提高Service的等级, 仔细看Service的API会发现这么个方法.
查 看官方API请点我
public final void startForeground (int id, Notification notification)

这个方法是从API 5开始的, 又说费话了. 但是用了之后会发现通知栏会弹出个通知, 不弹通知人家让你传Notification干嘛, 哦, 好吧, 我又NC了. 这就很好的解释了360和LBE这些软件的那个通知了. 那QQ,微信为什么没有呢. 方法是死的, 人是活的.
我们可以这样.
private void startForegroundCompat() {
try {
if (Build.VERSION.SDK_INT < 18) {
Log.v(TAG, "startForgroundCompat");
startForeground(1120, new Notification());
}
} catch (Exception e) {
if (DEBUG) Log.e(TAG, "", e);
}
}

为什么要低于版本18呢, 那你这句就问的就是废话了. 有Bug呗, 开个玩笑, 在版本18以及以上, 会弹出个默认的通知, so, 要低于版本18.
那有人可能又想, 那我们写成这样呢.
startForeground(1120, null);

当然也不行了, 要是行还new个空的干嘛, 这样会报错滴.
如果这样做之后, 你会发现一键清理对你的Service是完全不起作用的(再也没有那该死的正在重新启动了, 你这么吊, 你经理知道吗, 啊. 啊). 你可以哈哈大笑了, 总算解决了个残留很久的问题了. 但是别高兴太早, 一切都是有条件的. 实现以上效果必须系统同意你开机启动(开机启动? 跟着有毛关系? 唉....且看下文), 测试机型MIUI V5, 我也不知道它的那个自启动管理怎么做的, 我去了开机启动的权限以及广播, 它那里还是会显示, 只有点允许才OK, so, 如果你的用户大多是MIUI系统的话, 要想在那里面自动允许, 只能商务了, 要不你也可以像360那样, 整个引导界面, 让用户操作.
网上还有说通过startCommand的返回值让Service是否重新启动, 我觉着这样很不好.
第一, 用户清理这是一对多的关系,也许用户并不想清理你的程序呢(当然这概率有点小. 你又不是微信, 人家是拿到船票的人, 跟你我屌丝能一样吗), 所以这样做的必要是有的. 好像跟上面的问题没多大关系啊.
其二, 我想清理, 结果你还重新启动, 哇靠, 这什么APP, 这么流氓, 关键我都定位到你那个详情了, 点停止你还启, 点停止你还启...比如那个类微信...(当然也可以清理, 等它重新启动的时候再停止一次, 就See Bye了)
最后, 咱最终还是本着决定权在用户手里的原则, 你要是真的让我走, 我绝不死机白咧, 但是我得知道, 你真的指的是我, 走, 也要走的唯一!
按常理的话, 题目的解释到这里就完成了.
但是我这人吧, 就喜欢多做一点点. 永远超出别人的预期. 吼哈....
有的人会想, 那我API18以后怎么办, 我, 我, 我也不知道撒...
但是我可以保证的是, 只要用户不删你的APP, 你的服务就可以一直是活动的.
<receiver android:name=".NotifyReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.TIME_SET" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DATE_CHANGED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MEDIA_BAD_REMOVAL" />
<action android:name="android.intent.action.MEDIA_EJECT" />
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.MEDIA_REMOVED" />
<action android:name="android.intent.action.MEDIA_SCANNER_FINISHED" />
<action android:name="android.intent.action.MEDIA_SCANNER_STARTED" />
<action android:name="android.intent.action.MEDIA_SHARED" />
<action android:name="android.intent.action.MEDIA_UNMOUNTED" />
<data android:scheme="file" />
</intent-filter>
</receiver>

你注册这么个广播接收器, 在里面启动你的Service(当然启动的时候最好判断下是否启动), 除非用户不操作手机, 不安装, 不卸载, 网络环境一直不变化. 否则, 嘿嘿
What, 我这是在扇自己的脸吗. 我只是说有这么个方案, 当然不太建议大家去这么做, 简直太流氓了, 反正我是这么做了. 需求让人迷失自己!!! 迷失 Noooooooo, 程序员是没有自己的.

Ⅹ android进程管理机制

Android系统与其他操作系统有个很不一样的地方,就是其他操作系统尽可能移除不再活动的进程,从而尽可能保证多的内存空间,而Android系统却是反其道而行之,尽可能保留进程。Android这样设计有什么优势呢?又是通过怎样的方法来管理这些被保留的进程的呢?Android用户又该如何正确使用手机从而更好发挥Android系统所特有的优势呢?本文将一一为您解开这些谜团。

      本文的主要内容如下:

一、Android进程管理的特殊设计

       Linux系统对进程的管理方式是一旦进程活动停止,系统就会结束该进程。尽管Android基于Linux Kernel,但在进程管理上,却采取了另外一种独特的设计:当进程活动停止时,系统并不会立刻结束它,而是会尽可能地将该进程保存在内存中,在以后的某个时间,一旦需要该进程,系统就会立即打开它,而不用再做一些初始化操作。只有当剩余内存不够用了,为了维持新开启的进程或者比较重要的进程的正常运行,系统才会选择性地杀掉一些不重要的内存,腾出内存空间来,所以Android系统永远不会有内存不足的提示。

二、Android独特进程管理设计的好处

      Android这种独特的设计,也正是Android标榜的优势之一,这有两个好处:

  1、最大限度地提高内存的使用率。

       比如,你的内存是8G,如果每次使用完某个进程就杀掉,那么被使用的内存基本上会始终保持在某个值,比如4G以内,那么内存的使用率就总是保存在50%以内,剩余的4G内存形同虚设,发挥用处的机会非常少。而Android的这种设计,就可以做到有多少内存就用多少内存,尽可能大地提高内存使用率。同样比如有8G内存,使用完的进程仍保留在内存中,累积下来,被使用的内存就尽可能地会接近8G。

  2、提高再次启动时的启动速度

       被驻留在内存中不再活动的进程(后台进程或空进程,后面会再讲到),很多是经常需要使用的,当再次使用该进程的时候,系统立即打开它,而不需要再重新初始化。例如,我们常用的浏览器,当暂时不再使用时,按下Home键或Back键,浏览器进程就变成了不再活动的进程。如果下次又要使用了,点击多任务键,在最近使用应用列表中点击浏览器即可,浏览器界面仍然保持着退出前的界面。但如果退出时把该进程移除了,那么再次使用时,就需要重新初始化,然后进入该应用,这往往会花费不少的时间。

三、Android进程的五个等级

        Android系统将尽量长时间地保持应用进程,但为了新建进程或运行更重要的进程,最终需要移除旧进程来回收内存。为了确定保留或终止哪些进程,系统会根据进程中正在运行的组件以及这些组件的状态,将每个进程放入“重要性层次结构”中。必要时,系统会首先消除重要性最低的进程,然后是重要性略逊的进程,以此类推,以回收系统资源。该“重要性层级结构”将进程分为了五个等级:

  1、前台进程(foreground)

       前台进程是指那些有组件正和用户进行交互的应用程序的进程,也称为Active进程。这些都是Android尝试通过回收其他应用程序来使其保持相应的进程。这些进程的数量非常少,只有等到最后关头才会终止这些进程,是用户最不希望终止的进程。例如:而当你运行浏览器这类应用时,它们的界面就会显示在前台,它们就属于前台进程,当你按home键回到主界面,他们就变成了后台程序。

       如果一个进程满足以下任一条件,即视为前台进程:

     (1)托管处于活动状态的Activity,也就是说,它们位于前台并对用户事件进行响应,此时的情形为响应了Activity中的onResume()生命周期方法,但没有响应onPause()。

     (2)托管正在执行onReceive()方法处理事件程序的BroadcastReceiver。

     (3)托管正在执行onStart()、onCreate()或onDestroy()事件处理程序的Service。

     (4)托管正在运行且被标记为在前台运行的Service,即调用了该Service的startForeground()方法。

     (5)托管某个Service,且该Service正绑定在用户正在交互的Activity的Service,即该Activity正处于活动状态。

  2、可见进程(visible)

        没有任何前台组件、但仍然会影响用户在屏幕上所见内容的进程。如果一个进程满足以下任一条件,即视为可见进程:

    (1)托管不在前台、但仍对用户可见的Activity(已调用其onPause()方法)。例如:如果前台Acitivty启动了一个对话框,或者启动了一个非全屏,亦或是一个透明的Activity,允许在其后显示上一个Activity,则可能会发生这种情况,这类Activity不在前台运行,也不能对用户事件作出反应。

    (2)托管绑定到可见Activity的Service。(官网上说是绑定到可见或前台Activity,但笔者有一点疑问,这个和“前台进程”中第(5)点相矛盾吗,绑定到前台Activity,那就是前台进程了)

        可见进程被视为是极其重要的进程,这类进程的数量也很少,只有在资源极度匮乏的环境下,为保证前台进程继续执行时才会终止。

  3、服务进程(Service)

        正在运行已使用startService()方法启动的Serice且不属于上述两个更高类别进程的进程。尽管服务进程与用户所见内容没有直接关联,但是它们通常在执行一些用户关心的操作。因此,除非内存不足以维持所有前台进程和可见进程同时运行,否则系统会让服务进程保持运行状态。

       有些资料上面也称这种进程为次要服务(Secondary Service),而属于上述两个更高类别的进程则被称为主要服务,主要服务往往属于系统进程,如拨号进程等,不可能被进程管理轻易终止。这里我们以Android开发者官网的称呼为标准,称为服务进程。

  4、后台进程(hidden)

       包含目前对用户不可见的Activity,即该Activity调用了onStop()方法。这些进程对用户体验没有直接影响,系统可能随时终止它们,以回收内存供上述三个更高级别的进程使用。通常会有很多后台进程在运行,它们会保存在LRU(Least Recently Used,最近最少使用)列表中,以确保包含用户最近查看的Activity的进程最后一个被终止。如果某个Activity正确实现了生命周期方法,并保存了其当前状态,则终止其进程不会对用户体验产生明显影响,因为当用户导航回该Activity时,Activity会恢复其所有可见状态。

       这里读者可以做个试验,先开启微信,进入到朋友圈界面, 然后点击手机屏幕下方的导航栏中的Home按键进入到后台,再点击最近使用应用列表显示按钮(不同的手机位置不一样,有的在Home键左边,有的则在Home键右边),在显示的最近使用应用的列表中清理掉微信应用,最后再点击桌面的微信图标启动微信,会发现显示的界面仍然是朋友圈界面。

       后台进程,我们可以简单理解为,应用(只考虑只有Activity组件的情况)启动后按Home键后被切换到后台的进程。如浏览器、阅读器等,当程序显示在屏幕上时,它们所运行的进程即为前台进程(foreground),一旦按home键(注意不是back键)返回到桌面,程序就停留在后台,成为后台进程。

  5、空进程(empty)

       不含任何活动应用组件的进程。保留这种进程的唯一目的是用作缓存,以缩短下次再其中运行组件所需要的启动时间。一般来说,当应用按back按键退出后应用后,就变成了一个空进程。比如BTE,在程序退出后,依然会在进程中驻留一个空进程,这个进程里没有任何数据在运行,作用往往是提高该程序下次的启动速度或者记录程序的一些历史信息。当系统内存不够用时,无疑,该进程是应该最先终止的。在最近使用应用列表中,可以看到按back键退出的应用。

       根据进程中当前活动组件的重要程度,Android会将进程评定为它可能达到的最高级别。通俗地说,就是如果一个进程同时拥有多个对应上述不同等级进程的组件时,会以最高的那个等级作为该进程的等级。例如,如果某进程托管着服务和可见Activity,则会将此进程评定为可见进程,而不是服务进程。

       此外,一个进程的级别可能会因为其他进程对它的依赖而有所提高,即服务于另一进程的进程其级别永远不会低于其所服务的进程。例如,如果进程A中的内容提供程序为进程B中的客户端提供服务,或者如果进程A中的服务绑定到进程B中的组件,则进程A始终被视为至少与进程B同样重要。

       由于运行服务的进程其级别高于托管后台Activity的进程,因此启动长时间运行操作的Activity最好为该操作启动Service,而不是简单地创建工作线程,当操作有可能比Activity更加持久时更应该如此。例如,正在将图片上传到网站的Activity应该启动服务来执行上传,这样一来,即使用户退出Activity,仍可在后台继续执行上传操作。使用服务可以保证,无论Activity发生什么情况,该操作至少具备“服务进程”优先级。如果某个Activity开启了线程执行耗时操作,当Activity退出时,该Activity的实例将不会释放内存资源,直到线程执行完,这样容易导致内存泄漏。同理,广播接收器也应该使用服务,而不是简单地将耗时冗长的操作放入线程中。

四、进程移除顺序的依据——阈(yu,第四声)值

        前面讲到,内存不够用时,会根据进程的等级来决定优先回收哪类进程。那么系统是根据什么来判断需要移除这些进程的时机的呢?答案是阈值。

  1、查看阈值

        我们可以采用如下方法查看手机中各个等级进程的阈值(需要root权限),如第二排数据所示(其单位为页):

       以第一个数据44032为例,计算方法为:

       1page=4KB=4*1024B=4096B

       44032page* 4048B/page =  180355072B

       180355072B/1024/1024 = 172M

       即第一个等级的进程的阈值为172M。依次类推,阈值依次为:172M,190M,208M,226M,316M,415M。

       有必要说明一下,在Android开发者官方文档中,是将Android应用进程分为了5个等级,但很多资料却是分的6个等级,在后台进程和空进程之间还有一个“内容提供节点(content provider)进程”。内容提供节点,没有实体程序,仅提供内容供别的程序去用 ,比如日历供应节点,邮件供应节点等,在终止进程时,这类进程有比较高的优先权。手机中应该是采用的6个等级的方式,如上六个数据,正好对应着六个等级的进程,等级越高,阈值越低,即前台进程阈值为172M,空进程为415M。当系统的剩余内存只剩余不到415M的时候,系统首先会回收空进程,依次类推,只有剩余内存不到172M了,才会去回收前台进程,这样就起到了优化保护重要进程的作用。

五、Home键、Back键和多任务键

       Home键、Back键和多任务键,在手机屏幕的下方,这三个按键一般称为导航栏,中间的按钮为Home键,多任务键和Back键分别在其左右,一般根据手机品牌不同,左右位置也有所差异。

       在运行App的时候,如果按一下Home键或者Back键,都可以退到桌面,那么这两者有什么区别呢?

Home键。按Home键的时候,App如果没有Service开启,会从一个前台进程转变为一个后台进程;如果有前台service运行,就仍然是前台进程,比如QQ音乐播放器等;如果是只有普通service运行,那么就转变为服务进程(参照前文中讲的Android进程的5个级别)。

Back键。按Back键的时候,App如果没有Service开启,会从一个前台进程转变为一个空进程;对于有Service运行的情况,和按Home键一样。

        后台进程和空进程,都是驻留在后台,处于暂停状态,也都是除了占用一部分内存外,不占用其他如cpu等资源的,那么问题来了,为什么要设计后台进程和空进程这两种空进程呢?它们的区别到底在哪里呢?我们在前文讲Android进程的5个等级的时候讲到过,当剩余内存不足的时候,系统会按照等级顺序,优先移除不太重要进程,以收回内存供更重要的进程运行。那么,它们的区别就是,在剩余内存不足时,会优先移除空进程,再不足,才会移除空进程。所以,如果确实要退出某个应用一段时间内不大使用了,如果这款应用有退出按钮,就用应用自带的退出功能;如果没有,则最好按系统的Back键,这样可以变成空进程,当系统要回收内存时,就会优先被回收,从而释放的所占的资源。如果只是暂时退出去做点别的,过一会还要切换回来,或者对这款应用使用比较频繁,那就使用Home键,因为相比于按Back键,这样可以尽可能保住后台进程,方便下次使用的时候快速启动。

       当然,按Home键或Back键,对用户来说,其实感觉不到差异,使用起来没什么两样,但是,对于Android开发者来说,却有必要作为常识来了解其中的道理和差异。无论是按Home键还是按Back键,在按多任务键的时候,都可以看到这些进程,如下图所示。最下面的按键为清理按键,点击后可以清除掉这些进程,回收内存了,当然,前面也讲了很多遍了,不建议这样做。

  2、修改阈值。

       可以采用命令:echo "44032,48640,53248,57856,80896,106241" > /sys/mole/lowmemorykiller/parameters/minfree来修改阈值,如下所示:

       重启后,会恢复为原来的值。至于如何永久性修改该阈值,这里不深入探讨,有兴趣的童鞋可以自行研究,一般来说,就按照系统给定的默认值使用就可以了,没特殊用途的话,没必要修改。

       对于这一节阈值的内容,暂时先讲到这里,如果要更深入,可以自行多研究研究。笔者也没有看到比较好的更深入的文章,所以也不好推荐,如果读者看到比较好的,可以推荐给笔者,感激不尽。

六、开发者选项中的进程管理功能

        Android手机都带有开发者选项,隐藏了很多功能,顾名思义,这些功能主要用于辅助开发者调试程序用的。其中有一些就是关于进程管理功能的,笔者这里简单介绍一下其中两款,如下图红框部分所示:

不保留活动。用户离开以后即销毁每个活动(Activity),这样做使得后台进程都被销毁了。笔者试验过几款app,比如微信,浏览器,开启/关闭“不保留活动”前后,按Home键后,再打开应用,有明显的差别。当然,也试用了短信,DD打车,就没看出起了什么作用。读者若是感兴趣可以深入研究研究,到时候在指导指导笔者!

后台进程限制。如下图所示,给出了后台进程个数限制的选项。

七、进程管理软件的使用

       Windows操作系统用户往往总想着保留更多的内存,在使用Android手机的时候,喜欢经常清理后台进程或空进程,而且清理完后,心里有一种特别爽的感觉,就像给家里做了一次大扫除一样,笔者最初使用Android手机的时候也是这样的心态-_-!基于这样的心态,一些进程清理软件,很受普通用户的青睐。其实这样做却正好抹杀了Android系统所标榜的优势,如前文所讲到的。

       那么进程管理软件有无必要呢?当然有的,只是需要注意使用场合。当需要运行大型程序的时候,可以手动关闭掉一些进程,腾出足够的空间供大型程序使用,这样就可以有效避免系统调用进程调度策略而引起的卡顿,这一点,第八大点第3小节中会有说明。而且由于开发者的原因,可能是程序写得太烂,或程序容易出错,或做不该做的动作,或是恶意程序,对于这类程序进程,手动移除也是有好处的。

       但如果是运行一些小程序,就完全没有必要去预先杀进程了,完全可以交给系统自己管理。读者可能会疑惑,因为小程序启动的时候,也有可能会因为内存不足而导致需要移除部分进程的情况。笔者认为,即便是内存不足,小程序运行引起的调用进程调度策略测的次数非常少,要移除的进程也非常少,产生的影响不大。同时,我们也要意识到另外一点就是,无论是手动杀死进程还是自动杀进程,都需要cpu去执行这些任务,所以也会拖慢手机和消耗电量。所以从这一点看,频繁杀进程,也是一个不好的习惯。

八、答疑解惑

        在以前没有专门去了解Android进程管理机制的时候,甚至是在研究的过程中,笔者心里都经常存在很多疑惑,以下整理了其中5个,不知道读者您是否有也类似的困惑呢?

  1、这么多驻留在内存的进程,不会耗电吗?

       大多数用惯了Windows操作系统的童鞋,看到Android系统尽可能保留不在活动的进程的设计,可能第一反应就是质疑,难道这样不会增加耗电量吗?其实,但一个程序按home键变成后台进程或者按back键退出变成空进程后,其实已经被暂停了,只保留了运行状态,不会消耗cpu,一个程序会耗电,是因为它需要调用cpu来运算,现在不消耗cpu了,当然就不会耗电了。当然,开了service的应用就另当别论了,比如QQ音乐播放器,当按home键或back键后,音乐仍然播放,是因为它开启了服务,而且是一个前台服务,在后面我们会继续讲到,此时它是一个前台进程,而不是后台进程或空进程。

  2、为什么一个不太app,运行时会占用很大的内存呢?

我们经常会碰到这样一种现象,一个只有20M的App,运行起来的时候,却会耗掉100M以上的内存。一方面是,程序运行时为对象分配内存,另一方面,是Android虚拟机的原因。Android中的应用启动的时候,系统都会给它开启一个独立的虚拟机,这样做的好处是可以避免虚拟机崩溃导致整个系统崩溃,代价就是耗用更多的内存。

  3、为什么内存少的时候,运行大型程序会卡顿呢?

        当剩余内存不多时,打开大型程序,系统会触发自身的进程调度策略,去移除一些等级比较低的进程来回收内存,以供大型程序运行。而这个进程调度策略在决定哪些进程需要被移除的过程,是一个十分消耗资源的操作,特别是一个程序频繁像系统申内存的时候,这样就导致了系统的卡顿。

 4、应用开得太多了,手机变慢,是因为内存被占用太多吗?

        其实手机变慢的根本原因是cpu被耗用太多,而不是内存占用太多,因为真正执行程序所要完成的任务的最终执行者是CPU,而不是内存(RAM)。在内存足够的情况下,如果系统中占用cpu的进程太多,那无疑cpu总有忙不过来的时候,那肯定就会变慢了。这就好比,在一条道路上驾车,道路就像内存,车的引擎就像cpu,如果车的引擎的动力不够,或者承载的货物太多,车都跑不快,即便是道路上一路畅通无阻,也无济于事。所以,内存占用多少并不重要,只要道路提供给车辆前行的空间是足够的,手机变慢的责任,就和内存无关了。这个比喻用来解释第三点也很恰当,道路提供的车辆前进的空间无法满足车辆所必需的空间时,就需要交通机制花时间来调节交通,给这辆车提供足够的空间,而在此期间,这辆车只能乖乖候着。

  5、Android手机越用越慢,是什么原因呢?

Android手机常常是越用越慢,即使是恢复出厂设置,也无法改变这个现象。手机越用越慢,主要由如下几个原因:(1)虚拟机机制问题。这一点在上一个问题中也提到了,在Android4.4以前的系统,使用的是Dalvik虚拟机,它的设计机制有缺陷,就是越用越慢;在Android4.4系统中有切换按钮,可以在Art虚拟机和Dalvik虚拟机之间切换;在Android4.4以后的系统就彻底抛弃了Dalvik而全面使用Art。(2)开启了太多的服务,导致耗用太多的CPU。随着手机开机使用时间的增长,应用使用越来越多,很多应用看似退出了,而其实后台可能开了不少的服务,而他们可能还没有关闭。这些服务正在执行一些操作,会消耗CPU,而CPU才是手机变慢的根本原因。 而且Android app比较开放的,有很多不良应用充斥其中,可能对服务处理不当,滥用服务等,增加系统中的服务。(3)系统频繁调用自身的进程调度算法。这一点在前面已经说明了,这里不再赘述。(4)手机硬件的自然老化

热点内容
换编程题库 发布:2024-05-18 18:00:58 浏览:561
如何使用服务器ip直连网站 发布:2024-05-18 18:00:49 浏览:431
三星n7100哪个安卓版本好用 发布:2024-05-18 17:55:41 浏览:489
万国觉醒采集脚本源码 发布:2024-05-18 17:55:39 浏览:946
sqlserver加字段 发布:2024-05-18 17:54:53 浏览:927
安卓手机如何清除应用记录 发布:2024-05-18 17:31:37 浏览:639
查看存储过程权限 发布:2024-05-18 17:18:33 浏览:191
php类self 发布:2024-05-18 17:15:03 浏览:894
手机2b2t的服务器地址是多少 发布:2024-05-18 17:14:56 浏览:188
戴尔8490哪个配置比较合理 发布:2024-05-18 17:14:51 浏览:168