Android Service提高优先级

本文讲解了如何通过将Android Service设置为前台服务来提高其在系统内存管理中的优先级,防止在资源紧张时被系统终止。
        Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用。当系统觉得当前的资源非常有限的时候,为了保 证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存。这样就能保证真正对用户有用的程序仍然再运行。如果你的 Service 碰上了这种情况,多半会先被杀掉。但如果你增加 Service 的优先级就能让他多留一会,我们可以用 setForeground(true) 来设置 Service 的优先级。

  为什么是 foreground ? 默认启动的 Service 是被标记为 background,当前运行的 Activity 一般被标记为 foreground,也就是说你给 Service 设置了 foreground 那么他就和正在运行的 Activity 类似优先级得到了一定的提高。当让这并不能保证你得 Service 永远不被杀掉,只是提高了他的优先级。

  从Android 1.5开始,一个已启动的service可以调用startForeground(int, Notification)将service置为foreground状态,调用stopForeground(boolean)将service置为 background状态。

  我们会在调用startForeground(int, Notification)传入参数notification,它会在状态栏里显示正在进行的foreground service。background service不会在状态栏里显示。

  在Android 中,将一个service置为foreground状态:

Java代码:
   
  1. setForeground(true);
  2. mNM.notify(id, notification);
      将一个service置为background状态:

Java代码:
 
  1. mNM.cancel(id);
  2. setForeground(false);

       对比看出,在1.0 API中调用setForeground(boolean)只是简单的改变service的状态,用户不会有任何觉察。新API中强制将 notification和改变service状态的动作绑定起来,foreground service会在状态栏显示,而background service不会。

  Remote service controller & binding
  跨进程调用Service。暂时不研究。
### 临时提升进程优先级的实现原理及方法 在Android系统中,进程优先级的动态调整是通过`OomAdjuster`机制实现的,该机制负责根据进程的运行状态和系统资源状况动态更新进程的OOM(Out of Memory)评分。进程的OOM评分决定了其在资源紧张时被冻结或终止的可能性。在某些特定场景下,系统需要临时提升某个进程的优先级,以确保其能够获得足够的资源继续执行[^4]。 #### 1. 进程优先级的动态调整机制 Android系统中,每个进程都有一个`oom_adj`值,表示其被系统回收的优先级。数值越小表示优先级越高,越不容易被系统杀死或冻结。这个值由`ActivityManagerService`根据进程的组件状态(如是否包含前台Activity、Service、Receiver等)进行动态更新。当一个进程包含多个组件时,取其中优先级最高的组件对应的`oom_adj`作为该进程的最终优先级[^4]。 例如,如果一个进程同时包含一个前台Activity和一个后台Service,那么它将被赋予前台进程的优先级,因为前台Activity的优先级高于Service。 #### 2. 临时提升优先级的实现方式 在某些场景下,例如某个后台服务需要执行关键任务(如推送通知处理、数据同步等),可以通过绑定到前台组件(如前台Service)的方式临时提升其优先级。 具体实现方法包括: - **绑定到前台组件**:通过调用`startForeground()`方法将Service提升为前台Service,从而使其所在的进程优先级提升至接近前台进程的级别。此时,该进程的`oom_adj`值会显著降低,系统不会轻易冻结或杀死该进程。 ```java // 示例:将 Service 提升为前台服务 public class MyForegroundService extends Service { @Override public void onCreate() { super.onCreate(); Notification notification = new Notification.Builder(this, "channel_id") .setContentTitle("Foreground Service") .setSmallIcon(R.drawable.ic_notification) .build(); startForeground(1, notification); } @Override public IBinder onBind(Intent intent) { return null; } } ``` - **绑定到高优先级组件**:若某个进程与一个Activity绑定,并且该Activity处于前台状态,那么该进程的优先级也会被提升至前台级别。 - **使用`maxAdj`限制**:进程可以通过设置`maxAdj`来限制其优先级的上限,防止被系统降级。例如,某些系统关键进程会设置较低的`maxAdj`值以确保其始终处于高优先级状态[^4]。 #### 3. 优先级调整的底层实现 在Linux内核层面,优先级的调整依赖于nice值和调度策略。nice值的范围为[-20, 19],数值越小表示优先级越高。进程可以通过`setpriority()`系统调用调整其nice值,从而影响调度器对其的优先级判断。Android系统在此基础上结合`OomAdjuster`机制,将Java层的`oom_adj`值映射为内核调度优先级,实现对进程行为的精细控制[^2]。 #### 4. 应用场景与注意事项 临时提升进程优先级适用于需要保证执行连续性的场景,如: - 推送消息处理 - 实时数据同步 - 前台下载任务 - 语音识别或定位服务 但需注意的是,频繁或不必要地提升进程优先级可能导致系统资源分配不均,影响其他进程的正常运行,甚至引发“资源饥饿”问题。因此,开发者应根据实际需求合理使用该机制,避免滥用[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值