美文网首页APP拉活-保活内容
Android保活/拉活(二)代码实现

Android保活/拉活(二)代码实现

作者: 普通的程序员 | 来源:发表于2018-03-05 14:48 被阅读0次

    之前学习保活/拉活查资料写了一篇:
    Android保活/拉活(一)教程检索
    https://www.jianshu.com/p/b51e2dbf2311

    用到了jobSchedule,但是一直在报错,然后又偶然接触到了NotificationListenerService,决定重新再折腾一次,完整代码见文章最后。

    本文所有代码参考源为检索中的文章,做了整理注释及测试,转载请贴上检索链接
    https://www.jianshu.com/p/b51e2dbf2311
    https://www.jianshu.com/p/ce60fcedd3d6
    

    ----正文开始
    假定你已经非常明白LMK的原理,那么保活的关键点在降低oom_adj值,这样app在打开后进入后台,抗击厂商清理/第三方清理,能多苟1s
    建议绑定home键和back键事件

    保活

    环境情况

    在没有任何的保活措施情况下,前台oom_adj=0,后台7
    测试机型 红米4A root 6.0


    只有一个主进程

    方案1.开启前台服务降低oom_adj

    关键代码在创建服务,开启一个带通知栏的服务(可以再开一个服务把常驻通知栏取消,实测不影响前台服务的oom_adj)

        public void onCreate() {
            super.onCreate();
            //如果API大于18,需要弹出一个可见通知
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
                Notification.Builder builder = new Notification.Builder(this);
                builder.setSmallIcon(R.mipmap.ic_launcher);
                builder.setContentTitle("");
                builder.setContentText("");
                startForeground(NOTICE_ID, builder.build());
                // 如果觉得常驻通知栏体验不好
                // 可以通过启动CancelNoticeService,将通知移除,oom_adj值不变
                Intent intent = new Intent(this, CancelNoticeService.class);
                startService(intent);
            } else {
                startForeground(NOTICE_ID, new Notification());
            }
        }
    

    测试效果,主进程在变为后台时0->7,服务oom_adj不变


    实测效果

    *锁屏情况和按home键进入后台一样

    方案2.监听锁屏事件开启1像素界面

    关键代码在监听锁屏事件创建一个1像素的activity到前台

    public class ScreenBroadcastReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (mStateReceiverListener == null) return;
                String action = intent.getAction();
                Log.d("KeepAppAlive", "SreenLockReceiver-->监听到系统广播:" + action);
                if (action == null) return;
                switch (action) {
                    case Intent.ACTION_SCREEN_ON:
                        mStateReceiverListener.onScreenOn();
                        break;
                    case Intent.ACTION_SCREEN_OFF:
                        mStateReceiverListener.onScreenOff();
                        break;
                    case Intent.ACTION_USER_PRESENT:
                        mStateReceiverListener.onUserPresent();
                        break;
                }
            }
        }
    

    实测效果
    前台主进程oom_adj=0,后台=7,锁屏时=0


    image.png

    当我们查看最顶层的activity,就是我们的1像素activity
    我们的1像素activity要记得setFinishOnTouchOutside(true),
    避免有时候解锁杀死1像素activity不及时导致的界面卡死
    至于清单为什么这样设置,请参考


    image.png

    方案3.循环播放无声音乐

    方案1的进阶版,进liu阶mang的地方在于开启播放音乐,一些ROM是不会干掉正在播放音乐的app,测试机 华为P9,7.0,EMUI 5.0。
    另一些ROM会杀掉整个进程组,测试机一加5T,7.0&8.0,氢OS。

    关键代码就是播放音乐

     @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    startPlayMusic();
                }
            }).start();
            return START_STICKY;
        }
    

    这个方案的缺点也非常明显,耗电。

    拉活

    方案1.JobScheduler

    事务是官方推荐的做法。
    我在业务中实现,然后bugly的报错信息


    bugly报错

    搜一下这个bug,发现是个原生bug
    https://code.google.com/p/android/issues/detail?id=170814

    Android Jobscheduler使用
    https://www.jianshu.com/p/9fb882cae239

    https://www.jianshu.com/p/045b75f7d35c

    方案2.NotificationListenerService

    核心在打开NLS,使得自己可以使用通知。
    核心是获取通知监听权限,然后通过系统的保活来达到拉活目的。
    集成NLS很简单参考
    NotificationListenerService的那些事儿
    关键是下面链接说的问题
    https://www.zhihu.com/question/33540416
    我集成之后测试,仍旧无法实现拉活效果。。。所以这一条我先写上坑。

    方案3.监听系统广播并提高优先级

    参考信鸽的集成方案


    image.png

    有三个系统广播已经在7.0关闭静态注册方式
    https://www.cnblogs.com/JLZT1223/p/8108783.html

    总结

    因为众所周知的原因,我们没有一个统一的推送方案,如果用户不打开app,我们收不到推送的消息。
    是当用户打开app后,我们尽最大努力在后台情况下活下来--保活

    拉活的目的,是当app已经被杀死的情况下,尽最大努力调起--拉活

    就先这样吧

    代码地址:
    https://github.com/lamster2018/learnDaemon
    

    相关文章

      网友评论

        本文标题:Android保活/拉活(二)代码实现

        本文链接:https://www.haomeiwen.com/subject/brrqfftx.html