欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android防止Service被杀死 的实现方法

程序员文章站 2022-07-03 08:26:37
Service被杀死的两种场景 1. 系统回收和用户清除 在系统内存空间不足时可能会被系统杀死以回收内存,内存不足时Android会依据Service的优先级来清除Serv...

Service被杀死的两种场景

1. 系统回收和用户清除

在系统内存空间不足时可能会被系统杀死以回收内存,内存不足时Android会依据Service的优先级来清除Service。

用户可以在”最近打开”(多任务窗口、任务管理窗口)中清除最近打开的任务,当用户清除了Service所在的任务时,Service可能被杀死(不同ROM有不同表现,在小米、魅族等第三方产商定制ROM上一般会被立即杀死,在Android N上没有被立即杀死)。2. 解决方案

对于第一种场景(系统回收),如果不用黑科技(双进程互开等),我们只能够尽量提高Service的优先级,一种比较好的方式是使用前台Service。

对于第二种场景(用户手动清除),可以将启动Service的任务排除出系统的最近任务列表。

2.1 前台Service

前台Service是一种有前台界面(Notification)、优先级非常高的Service,只有在系统内存空间严重不足时,才会清除前台Service。

只需要在Service的?onStartCommand()?内调用startForeground,就能将Service转为前台Service。示例如下:

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (Build.VERSION.SDK_INT < 18) {
            startForeground(GRAY_SERVICE_ID, new Notification());//API < 18 ,此方法能有效隐藏Notification上的图标
        } else {
            Intent innerIntent = new Intent(this, GrayInnerService.class);
            startService(innerIntent);
            startForeground(GRAY_SERVICE_ID, new Notification());
        }
        //设置START_STICKY,服务被杀死可以重启该服务,但是Intent参数为null,
        // 也就是onStartCommand方法虽然会执行但是获取不到intent信息
        /**
         * 使用场景:如果你的Service可以在任意时刻运行或结束都没什么问题,
         * 而且不需要intent信息,那么就可以在onStartCommand方法中返回START_STICKY,
         * 比如一个用来播放背景音乐功能的Service就适合返回该值。
         * */
        flags = START_STICKY;
        return super.onStartCommand(intent, flags, startId);
    }
/**
     * 给 API >= 18 的平台上用的灰色保活手段
     */
    public static class GrayInnerService extends Service {

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startForeground(GRAY_SERVICE_ID, new Notification());
            stopForeground(true);
            stopSelf();
            return super.onStartCommand(intent, flags, startId);
        }

        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

    }

2.2 移出最近任务

为了使Service不会被用户从”最近打开”中清除,我们可以将启动Service的任务从系统的最近应用列表中删除。做法是将任务Activity的excludeFromRecents设为true,如下: