Android进程保活(如何尽可能避免APP被杀死)

编程入门 行业动态 更新时间:2024-10-27 17:20:27
#.Android进程的优先级 Android系统中进程有不同的优先级,在系统需要优化和回收资源时,会先杀死优先级低的进程。所以要保活一个进程,就要想办法尽可能去提升它的优先级。 ##1.前台进程 —— Foreground process 用户当前操作所必需的进程。通常在任意给定时间前台进程都为数不多。只有在内存不足以支持它们同时继续运行这一万不得已的情况下,系统才会终止它们。 A. 拥有用户正在交互的 Activity(已调用onResume()) B. 拥有某个 Service,后者绑定到用户正在交互的 Activity C. 拥有正在“前台”运行的 Service(服务已调用startForeground()) D. 拥有正执行一个生命周期回调的 Service(onCreate()、onStart()或onDestroy()) E. 拥有正执行其onReceive()方法的 BroadcastReceiver ##2. 可见进程 —— Visible process 没有任何前台组件、但仍会影响用户在屏幕上所见内容的进程。可见进程被视为是极其重要的进程,除非为了维持所有前台进程同时运行而必须终止,否则系统不会终止这些进程。 A. 拥有不在前台、但仍对用户可见的 Activity(已调用onPause())。 B. 拥有绑定到可见(或前台)Activity 的 Service ##3. 服务进程 —— Service process 尽管服务进程与用户所见内容没有直接关联,但是它们通常在执行一些用户关心的操作(例如,在后台播放音乐或从网络下载数据)。因此,除非内存不足以维持所有前台进程和可见进程同时运行,否则系统会让服务进程保持运行状态。 A. 拥有已启动且尚在运行未销毁的service,且不属于上述两个更高类别进程的进程。 ##4. 后台进程 —— Background process 后台进程对用户体验没有直接影响,系统可能随时终止它们,以回收内存供前台进程、可见进程或服务进程使用。 通常会有很多后台进程在运行,因此它们会保存在 LRU 列表中,以确保包含用户最近查看的Activity的进程最后一个被终止。如果某个 Activity 正确实现了生命周期方法,并保存了其当前状态,则终止其进程不会对用户体验产生明显影响,因为当用户导航回该 Activity 时,Activity 会恢复其所有可见状态。 A. 对用户不可见的 Activity 的进程(已调用Activity的onStop()方法) ##5. 空进程 —— Empty process 保留这种进程的的唯一目的是用作缓存,以缩短下次在其中运行组件所需的启动时间。 为使总体系统资源在进程缓存和底层内核缓存之间保持平衡,系统往往会终止这些进程。 A. 不含任何活动应用组件的进程 ##.小结       具体地,活动进程指的就是用户正在操作的程序,是前台进程,可以看到且能够操作;可见进程就是看得见摸不着的,不能直接操作的进程;服务进程是没有界面的一直在后台工作的进程,优先级不高,当系统内存不足时会被杀死,再次充裕的时候会再次开启;后台进程就是用户按了"back"或者"home"后,程序本身看不到了,但是其实还在运行的程序,比如Activity调用了onPause方法系统可能随时终止它们,回收内存.空进程:某个进程不包含任何活跃的组件时该进程就会被置为空进程,完全没用,杀了它只有好处没坏处,第一个被处理! #.内存阈值 (内容摘录自参考资料)   进程是怎么被杀的呢?系统出于体验和性能上的考虑,app在退到后台时系统并不会真正的kill掉这个进程,而是将其缓存起来。打开的应用越多,后台缓存的进程也越多。在系统内存不足的情况下,系统开始依据自身的一套进程回收机制来判断要kill掉哪些进程,以腾出内存来供给需要的app, 这套杀进程回收内存的机制就叫 Low Memory Killer。那这个不足怎么来规定呢,那就是内存阈值,我们可以使用cat /sys/module/lowmemorykiller/parameters/minfree来查看某个手机的内存阈值。 注意这些数字的单位是page. 1 page = 4 kb.上面的六个数字对应的就是(MB): 72,90,108,126,144,180,这些数字也就是对应的内存阀值,内存阈值在不同的手机上不一样,一旦低于该值,Android便开始按顺序关闭进程. 因此Android开始结束优先级最低的空进程,即当可用内存小于180MB(46080*4/1024)。   进程是有它的优先级的,这个优先级通过进程的adj值来反映,它是linux内核分配给每个系统进程的一个值,代表进程的优先级,进程回收机制就是根据这个优先级来决定是否进行回收,adj值定义在com.android.server.am.ProcessList类中,这个类路径是${android-sdk-path}\sources\android-23\com\android\server\am\ProcessList.java。oom_adj的值越小,进程的优先级越高,普通进程oom_adj值是大于等于0的,而系统进程oom_adj的值是小于0的,我们可以通过cat /proc/进程id/oom_adj可以看到当前进程的adj值。   也就是说,oom_adj越大,占用物理内存越多会被最先kill掉,OK,那么现在对于进程如何保活这个问题就转化成,如何降低oom_adj的值,以及如何使得我们应用占的内存最少。 #.保活手段     这里只给出两种最常见的方法:开启前台Service, Android 6.0以上版本,引导开启忽略电池优化开关。进阶方法参考剪藏内容。 ##1.开启前台Service     拥有前台Service的进程为活动进程,拥有关键优先级,能大大提升生命力。
让一个Service变成前台Service:
Android9.0以后启动前台服务需要权限: <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
1.创建一个通知Notification
2.调用Service的API弹出通知: startForeground(通知ID, Notification);
   可以调用stopForeground(boolean)将Service设置回后台Service,里面boolean参数控制是否同时移除通知。
   startForeground()弹出的通知,只有当Service变回后台服务,或者Service被杀死,才能移除,否则点击无法移除。
## 2.Android 6.0以上版本,引导开启忽略电池优化开关
/**
* 忽略电池优化辅助类
* APP加入手机忽略电池优化白名单,可以让APP拥有更强生命力,有效降低APP被系统杀死的优先级
* 需要权限:
* <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
*/
public class IgnoreBatteryOptimizationUtils {

    /**
     * app是否已经在手机忽略电池优化白名单中
     * @param context
     * @return
     */
    public static boolean isIgnoringBatteryOptimizations(Context context) {
        if(context == null){
            return false;
        }
        boolean isIgnoring = false;
        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (powerManager != null) {
            isIgnoring = powerManager.isIgnoringBatteryOptimizations(context.getPackageName());
        }
        return isIgnoring;
    }

    /**
     * 申请加入手机忽略电池优化白名单,会跳转到相关设置页Activity
     * 可以用startActivityForResult()来启动设置页,以便用户操作结束后,
     *      在onActivityResult()中根据是否已经加入白名单,来做相应提示。
     * @param activity
     */
    public static void requestIgnoreBatteryOptimizations(Activity activity, int requestCode) {
        if(activity == null){
            return;
        }
        try {
            Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
            intent.setData(Uri.parse("package:" + activity.getPackageName()));
            activity.startActivityForResult(intent, requestCode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void requestIgnoreBatteryOptimizations(Context context) {
        if(context == null){
            return;
        }
        try {
            Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
参考剪藏: Android进程保活(最新)带你浅析这几种可行性的保活方案 - 简书 优雅保活方案,原来Android还可以这样保活! - 简书

(声明:部分图片获取自网络,这里只是用于学习分享,侵删!)

更多推荐

Android进程保活(如何尽可能避免APP被杀死)

本文发布于:2023-06-13 10:03:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1378296.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:被杀   进程   Android   APP

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!