耍流氓式的保活service

QQ为什么一直常驻后台?
(白名单,双进程守护)
应用正在运行,这个时候内存不足回收杀进程

  • 1.提高进程的优先级,其实就是减小进程的p->oomkilladj(越小越重要),如启动Service调用startForeground()尽量提高进程的优先级;
  • 2.当应用退到后台适当释放资源然后降低APP的内存占用量,因为在oom_adj相同的时候,会优先干掉内存消耗大的进程;

双进程守护
MessageService

public class MessageService extends Service {
    private static final String TAG = MessageService.class.getSimpleName();

    @Override
    public void onCreate() {
        super.onCreate();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    Log.e("TAG", "等待接收消息");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //提高进程优先级
        //提高进程的优先级,其实就是减小进程的p->oomkilladj(越小越重要),
        // 如启动Service调用startForeground()尽量提高进程的优先级;
        startForeground(1, new Notification());
        //绑定服务
        bindService(new Intent(this, GuardService.class), mConnService, BIND_IMPORTANT);
        return START_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new ProcessAidl.Stub() {
        };
    }

    private ServiceConnection mConnService = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //绑定连接
            Toast.makeText(MessageService.this, "建立连接", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //解绑   重新启动 绑定服务
            startService(new Intent(MessageService.this, GuardService.class));
            //绑定服务
            bindService(new Intent(MessageService.this, GuardService.class), mConnService, Context.BIND_IMPORTANT);
        }
    };
}

GuardService

public class GuardService extends Service {
    private static final String TAG = GuardService.class.getSimpleName();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new ProcessAidl.Stub() {
        };
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //提高进程优先级
        //提高进程的优先级,其实就是减小进程的p->oomkilladj(越小越重要),
        // 如启动Service调用startForeground()尽量提高进程的优先级;
        startForeground(1, new Notification());
        //绑定服务
        bindService(new Intent(this, MessageService.class), mConnService, BIND_IMPORTANT);
        return START_STICKY;
    }

    private ServiceConnection mConnService = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //绑定连接
            Toast.makeText(GuardService.this, "建立连接", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //解绑   重新启动 绑定服务
            startService(new Intent(GuardService.this, MessageService.class));
            //绑定服务
            bindService(new Intent(GuardService.this, MessageService.class), mConnService, BIND_IMPORTANT);
        }
    };
}

ProcessAidl:空的Aidl

interface ProcessAidl {
}

此时我们可以发现我们软件是有双进程的,我们停止停不了,用了系统自带或者第三方的清理软件,也不会杀我们的进程,但是各大Rom厂商在应用退出的时候会清理杀进程。解决方法可以使用ndk,这里使用电量优化的方法

JobWakeUpService

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class JobWakeUpService extends JobService {
    private final int jobWakeUpId = 1;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        JobInfo.Builder builder = new JobInfo.Builder(jobWakeUpId,
                new ComponentName(this, JobWakeUpService.class));
        builder.setPeriodic(2000);
        // 开启一个轮寻
        JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);

        jobScheduler.schedule(builder.build());
        return START_STICKY;
    }

    @Override
    public boolean onStartJob(JobParameters params) {
        // 开启定时任务,定时轮寻 , 看MessageService有没有被杀死
        // 如果杀死了启动  轮寻onStartJob
        boolean messageServiceAlive = serviceAlive(MessageService.class.getName());
        if (!messageServiceAlive) {
            startService(new Intent(this, MessageService.class));
        }
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return false;
    }

    /**
     * 判断某个服务是否正在运行的方法
     *
     * @param serviceName 是包名+服务的类名(例如:net.loonggg.testbackstage.TestService)
     * @return true代表正在运行,false代表服务没有正在运行
     */
    private boolean serviceAlive(String serviceName) {
        boolean isWork = false;
        ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> myList = manager.getRunningServices(100);
        if (myList.size() < 0) {
            return false;
        }
        for (ActivityManager.RunningServiceInfo info : myList) {
            if (info.service.getClassName().equals(serviceName)) {
                isWork = true;
                return true;
            }
        }
        return isWork;
    }
}

配置manifest.xml文件

   <service
            android:name=".MessageService"
            android:enabled="true"
            android:exported="true" />
        <!--android:process=":guardProgress" 新建一个线程-->
        <service
            android:name=".GuardService"
            android:process=":guardService" />
        <service
            android:name=".JobWakeUpService"
            android:permission="android.permission.BIND_JOB_SERVICE" />

一定要添加权限:<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值