进程保活-踩坑篇

本文介绍了一种在Android应用被用户强制关闭后,通过特定服务保持应用后台运行的方法。主要利用KeepLiveService和KeepLiveBindService两个服务组件,通过轮询的方式确保关键服务持续运行。
摘要由CSDN通过智能技术生成

转载请注明出处
http://blog.csdn.net/brucehurrican/article/details/51753334

相信好多开发的朋友都遇到过这样的需求:app即使被用户kill掉,关键服务仍要存活,即app要有一个保活的进程来保障app一直存活于后台不被kill掉。网上关于进程保活的文章有很多,我这里用的方法也是在网上找的。说下我遇到的需求吧:

  • 服务所在保活进程一直运行在后台,并定时处理相应业务逻辑
  • 当主进程被用户kill掉,保活进程存活

我用的方法如下:

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

        if (Build.VERSION.SDK_INT < 18) {
            // API < 18 ,此方法能有效隐藏Notification上的图标
            startForeground(1001, new Notification());
        } else {
            Intent innerIntent = new Intent(this, KeepLiveInnerService.class);
            startService(innerIntent);
            startForeground(1001, new Notification());
        }
        LogDetails.getLogConfig().configShowBorders(true);
        LogDetails.i("保活服务开启-所在进程-" + android.os.Process.myPid());
        bindService(new Intent(this, KeepLiveService.class), new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // 待处理业务逻辑
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        },BIND_AUTO_CREATE);
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 给 API >= 18 的平台上用的灰色保活手段
     */
private static class KeepLiveInnerService extends Service {

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

            startForeground(1001, new Notification());
            stopForeground(true);
            stopSelf();
            return super.onStartCommand(intent, flags, startId);
        }

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

 <service android:name=".keeplive.KeepLiveService" android:process=":keeplive"/>

这种保活方式也是大家用的比较多的一种,我在项目中也是用此种方法,坑点是业务需要在service start后要bind上该服务并在service connected中进行处理。因为业务需求中有网络请求,IO操作等一些耗时的操作。这样导致用户在kill app后连带保活进程也被kill掉。根本原因是上述代码中的bindservice,所需绑定的context被kill掉导致该保活进程服务也被kill。

我的解决方法如下:

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

        if (Build.VERSION.SDK_INT < 18) {
            // API < 18 ,此方法能有效隐藏Notification上的图标
            startForeground(1001, new Notification());
        } else {
            Intent innerIntent = new Intent(this, KeepLiveInnerService.class);
            startService(innerIntent);
            startForeground(1001, new Notification());
        }
        LogDetails.getLogConfig().configShowBorders(true);
        LogDetails.i("保活服务开启-所在进程-" + android.os.Process.myPid());
        new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                startService(new Intent(KeepLiveBindService.this, KeepLiveService.class));
            }
        },2000,3000);
        return super.onStartCommand(intent, flags, startId);
    }
<service android:name=".keeplive.KeepLiveBindService" android:process=":keeplive2"/>
// 此处进程可与KeepLiveService一致,为了提高保活率我在工程使用不同的进程

新建另一个保活进程的服务在该服务中轮询业务进程服务KeepLiveService 这样可以达到业务需要,后台保活。

注意:
对于原生android系统,这种保活方式是有效果的。因android 碎片化和国内各种rom 对于第三方服务的控制是不一样的,我在做项目过程中,华为荣耀部分机型就可以保活成功,P系列就不行。小米全系列和MX系列都是不起作用的。

全部代码可以从我的github上下载。

如果您有更好的解决方法欢迎不吝赐教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值