https://www.jianshu.com/p/cfc2a200e46d
因为公司app要保活。像酷狗音乐,一直在后台播放音乐。所以研究了下
系统如何杀死进程?
内存阀值,不同进程优先级导致的不一样的阀值。
空进程:加快启动速度
ADJ
  • 红色部分是容易被回收的进程,属于android进程
  • 绿色部分是较难被回收的进程,属于android进程
  • 其他部分则不是android进程,也不会被系统回收,一般是ROM自带的app和服务才能拥有

如何查看某个进程的oom_adj数值呢?
oom_adj 存储在proc/PID/oom_adj文件中,其中PID是进程的id,直接 adb shell进入手机根目录查看这个文件即可。

演示一下:以我自己的项目为例,app中有两个进程,一个是主进程,另一个是运行service的进程取名为:remote。首先用android studio查看每个进程的PID:


查看命令
https://blog.csdn.net/u013179982/article/details/85697373
如何在studio中,手动杀死某个进程?
logcat里面的红色按钮。
降低自己应用在退回后台时候的oom_adj值
oom_adj
表格:
https://www.cnblogs.com/tiger-wang-ms/p/6491429.html
查看adj的值:

【1】adb shell

【2】ps

【3】cat /proc/进程id/oom_adj

举例:cat /proc/20084/oom_adj

OOM_adj:在不同的前台和后台不一样
目前看
1.在前台是0,后台是3
oom_adj值:前台和后台不一样
===================================================

优化思路:

  1. 提高进程的优先级,降低自己应用在退回后台时候的oom_adj值
  2. 在进程被kill之后能够唤醒
  3. 优化应用内存,正在进行中...
保活:1像素 ,后台播放音乐,前台进程
拉活:
保活分析:
1.通知栏(重点分析)
2.第三方推送(no)
不打包push模块。//include ':push'
3.TransferActivity(no)
4.友盟
分析方案:
1.先把yodo统一的文件,代码对比(ok)
2.一个一个注释掉。(ok)
3.看日志,是杀死的快?还是因为重新拉活了?
通过代码:发现yodo的锁屏
2.通知栏(ok)
3.自启动权限
通知栏
ServiceWakeKeepTicketProcess(ok)
ServiceWakeMainProcess(ok)
KeepAliveBlankVoice(ok)
KeepAliveTool

 
AlarmService
CMainJobService
CSportJobService
RemoteKeepAlive
LocationMonitorService
RepeatWorker
Android 使用MarsDaemon进程常驻====DaemonConfigurations
广播AlarmStepReceiver
电量广播:
YODO保活办法:
1.AlarmManager ===[无用] =定时唤醒(它比Service和定时器更加节省资源)
AlarmReceiver
2.AlarmService==[无用](CMonitorSportService,CMonitorMainService<2个都不是service,用于绑定service>)=====(CSportJobService,CMainJobService,和前面对应)<JobService>======(JobScheduler拉活)
binderService()不一定是Activity
3.BatterReceiver(电量广播拉活)
4.GuardReceiver第三方的包活[无用]
同上SportGuardService
5.Worker--------WorkManager
6.StartSystemReceiver  开机广播[无用]
7.Rejoice 里面通知栏:keepAliveTime
锁屏:
startRunFromLockScreen()
Rejoice的方法moveToHome()
被回收:通过上报,数据库中跑步状态的保存
PhoneStateListener:
通知栏:
需要不停的刷新通知栏的ui,让系统以为你是前台进程,这样就不会杀掉你了
白色保活方案:
1.后台自启动
2.和加入“手机白名单”
思路:

1.像素Activity

降低oom_adj的值。
当在后台的时候,用1像素
当在前台的时候,恢复
结果:在后台可以达到0
缺点:如果不是锁屏,不能达到这种效果

该方案适用场景: 本方案主要解决第三方应用及系统管理工具在检测到锁屏事件后一段时间内会杀死后台进程.适用于android所有版本。1像素Activity的特点: 需要设置该activity的style设置透明,在手机锁屏时start;在屏幕解锁时finish,主要作用就是在App退到后台之后且锁屏的时候启动一个看不见的Activity,造成一个该App没有回退到后台的假象,降低被杀的几率,伪代码如下:

  protected void onCreate(Bundle savedInstanceState) {protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);super.onCreate(savedInstanceState);

        //设定一像素的activity//设定一像素的activity

        Window window = getWindow();Window window = getWindow();

        window.setGravity(Gravity.START | Gravity.TOP);window.setGravity(Gravity.START | Gravity.TOP);

        WindowManager.LayoutParams params = window.getAttributes();WindowManager.LayoutParams params = window.getAttributes();

        params.x = 0;params.x = 0;

        params.y = 0;params.y = 0;

        params.height = 1;params.height = 1;

        params.width = 1;params.width = 1;

        window.setAttributes(params);window.setAttributes(params);

    }

    

 public void onReceive(final Context context, Intent intent) {public void onReceive(final Context context, Intent intent) {

        Log.i("ScreenStateReceiver", "---屏幕锁屏监听---");Log.i("ScreenStateReceiver", "---屏幕锁屏监听---");

        if (action.equals(Intent.ACTION_SCREEN_OFF)) {if (action.equals(Intent.ACTION_SCREEN_OFF)) {

           //屏幕锁定,开启OnePixelActivity//屏幕锁定,开启OnePixelActivity

        } else if (action.equals(Intent.ACTION_SCREEN_ON)) {else if (action.equals(Intent.ACTION_SCREEN_ON)) {

           //屏幕解锁,finish OnePixelActivity//屏幕解锁,finish OnePixelActivity

        }

    }

说起来很简单,但是还是有几个知识点需要注意下。

关于这一点有一个细节需要处理,为了放置用户快速 进行锁屏和截屏的切换操作,而导致OnePixelActivity频繁开关。需要用一个Handler发送一个延迟消息处理最佳:

   private Handler mHandler;private Handler mHandler;

    private boolean isScreenOn = true;private boolean isScreenOn = true;

    private PendingIntent  pendingIntent;private PendingIntent  pendingIntent;

    private List<ScreenStateListener> screenStateListeners = null;private List<ScreenStateListener> screenStateListeners = null;

    @Override@Override

    public void onReceive(final Context context, Intent intent) {public void onReceive(final Context context, Intent intent) {

        String action = intent.getAction();String action = intent.getAction();

      

        if (action.equals(Intent.ACTION_SCREEN_OFF)) {if (action.equals(Intent.ACTION_SCREEN_OFF)) {

           //标记屏幕为锁屏状态//标记屏幕为锁屏状态

            isScreenOn = false;isScreenOn = false;

            //开启一像素的Activity//开启一像素的Activity

            startOnePixelActivity(context);startOnePixelActivity(context);

        } else if (action.equals(Intent.ACTION_SCREEN_ON)) {else if (action.equals(Intent.ACTION_SCREEN_ON)) {

            //标记屏幕为解屏状态//标记屏幕为解屏状态

            isScreenOn = true;     isScreenOn = true;     

            if(pendingIntent!=null){if(pendingIntent!=null){

                pendingIntent.cancel();pendingIntent.cancel();

            }

     

        }

    }

  //开启一像素的Activity//开启一像素的Activity

 private void startOnePixelActivity(final Context context){private void startOnePixelActivity(final Context context){

        if(mHandler==null){if(mHandler==null){

            mHandler = new Handler(Looper.myLooper());mHandler = new Handler(Looper.myLooper());

        }

        mHandler.postDelayed(new Runnable() {mHandler.postDelayed(new Runnable() {

            @Override@Override

            public void run() {public void run() {

              //如果屏幕此时已经打开,则不执行//如果屏幕此时已经打开,则不执行

                if(isScreenOn){if(isScreenOn){

                    return;return;

                }

                if(pendingIntent!=null){if(pendingIntent!=null){

                    pendingIntent.cancel();pendingIntent.cancel();

                }

                

                Intent startOnePixelActivity = new Intent(context, OnePixelActivity.class);Intent startOnePixelActivity = new Intent(context, OnePixelActivity.class);

                startOnePixelActivity.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);startOnePixelActivity.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

                //启动一像素包活activity//启动一像素包活activity

                pendingIntent = PendingIntent.getActivity(context, 0, startOnePixelActivity, 0);pendingIntent = PendingIntent.getActivity(context, 0, startOnePixelActivity, 0);

                try {try {

                    pendingIntent.send();pendingIntent.send();

                } catch (Exception e) {catch (Exception e) {

                    e.printStackTrace();e.printStackTrace();

                }

                notifyScreenOff();notifyScreenOff();

            }

        },1000);1000);

    }

  <activity android:name=".OnePixelActivity"<activity android:name=".OnePixelActivity"

            android:theme="@style/onePixelActivity"android:theme="@style/onePixelActivity"

            android:launchMode="singleInstance"android:launchMode="singleInstance"

            android:excludeFromRecents="true"/>android:excludeFromRecents="true"/>

为什么需要将此Activity的启动模式设置为singleInstance呢?原因是因为如果设置成其他模式,如果按照如下步骤操作的话会出现不友好的状况:
1、启动App(比如进入MainActivity),按home键让app返回后台
2、锁定屏幕,此时注册好的监听广播会启动OnePixelActivity
3、解锁屏幕,此时广播接受到此广播后会finish 掉OnePixelActivity.
因为OnePixelActivity是非singleInstance,所以此时本来已经进入后台的MainActivity的页面会自动打开。给用户造成干扰:我明明已经按下home键了,怎么此页面又自动打开了?而换成OnePixelActivity的启动模式改成singleInstance的话就可以很好的避免此问题。

另外需要注意的是,当屏幕解锁的时候,OnePixelActivity的onResume得到执行,所以在该Activity的onResume方法执行finish效果最好:

//OnePixelActivity的onResume

   protected void onResume() {protected void onResume() {

        super.onResume();super.onResume();

      

        if (DeviceUtils.isScreenOn(this)) {//如果屏幕已经打开if (DeviceUtils.isScreenOn(this)) {//如果屏幕已经打开

            finish();finish();

        }

    }

2.播放无声音乐

播放无声音乐:原理:

处理逻辑跟OneActivity一样,在App回到后台且锁屏的时候在Service里播放一个无声的mp3文件,当解锁的时候暂停改mp3的播放。

if(screenOn){//屏幕解锁(screenOn){//屏幕解锁

    puseMp3();puseMp3();

}else{//锁屏else{//锁屏

   playMp3();playMp3();

所以此是可以在程序启动的时候启用这个service,在在service里面注册锁屏广播,需要注意的一些地方(此Service姑且称之为KeepAliveService):

//播放无声音乐的Service

public class KeepAliveService extends Service { class KeepAliveService extends Service {

    private boolean isScreenON = true;//控制暂停private boolean isScreenON = true;//控制暂停

    private MediaPlayer mediaPlayer;private MediaPlayer mediaPlayer;

    //锁屏广播监听//锁屏广播监听

    private ScreenStateReceiver screenStateReceiver;private ScreenStateReceiver screenStateReceiver;

    @Override@Override

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

        //注册锁屏广播//注册锁屏广播

        registerScreenStateReceiver();registerScreenStateReceiver();

        //初始化播放器//初始化播放器

        initMediaPlayer();initMediaPlayer();

        return START_STICKY;return START_STICKY;

    }

 }

需要注意的是在播放器播放的时候,需要判断当前情况是否是解屏状态,而且在播放完成监听里面,继续调用start方法循环播放mp3,部分代码如下(本篇博文只贴部分关键代码,全部代码点此查看):

后台播放声音:KeepAliveBlankVoice
缺点:
3.前台进程:
缺点:有通知栏
8.0以前可以不用通知栏的解决方案:

2、将HideNotifactionService调用startForeground将其设置为前台Service!
3、但是该Service调用startForeground方法的时候,第一个参数传的ID跟KeepAliveService调用时传同样的ID。

这样的话就确保有HideNotifactionService和KeepAliveService两个发送具有同样ID的Notification!

4、调用HideNotifactionService的stopSelf方法关闭自己,随着这个Service的关闭,通知栏的那条相同id的通知也就没了;但是同样确保了KeepAliveService的进程优先级得到了提高!

HideNotifactionService代码如下:

可以创建另一个Service,名为HideNotifactionService,该Service在KeepAliveService里面启动之

//KeepAliveService的onStartCommand方法

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

        //省略注册锁屏广播以及初始化播放器的代码//省略注册锁屏广播以及初始化播放器的代码

       //将自己设置为前台Service//将自己设置为前台Service

        startForeground(this);startForeground(this);

     //启动HideNotificationService//启动HideNotificationService

      startService(new Intent(this, HideNotificationService.class));startService(new Intent(this, HideNotificationService.class));

        return START_STICKY;return START_STICKY;

    }


前面3种是保活方案
拉活方案:

一。JobServcie 拉活

原理:它将后台任务调度直接交给系统服务(JobSchedulerSevice)管理,并且可以设置许多约束条件,如周期调度,延迟调度,网络连接,电源插入,还有AndroidL引入的空闲模式。在条件符合的情况下,系统服务BindService的方式把应用内Manifest中配置的JobService启动起来,并通过进程间通信Binder方式调用JobService的onStartJob、onStopJob等方法来进行Job的管理。即便在执行任务之前应用程序进程被杀,也不会导致任务中断,Jobservice不会因应用退出而退出 当然JobScheduler不只是用于保活这个黑科技,可以利用这种机制做很多后台定时任务。
二。账号同步机制拉活
缺点:时间不确定
三。workManager 拉活
四。BatterReceiver(广播拉活)
缺点:失效
五。
https://www.jianshu.com/p/dd01580743e7(1像素)
AAR:
https://github.com/Ray512512/KeepAlive
8.0(双守护)
https://juejin.im/entry/6844903764269219847
保活:
https://www.jianshu.com/p/8f258aedcdcb(多种方案)
https://blog.csdn.net/chunqiuwei/article/details/95649955(锁屏)
得到:
https://blog.csdn.net/hello_json/article/details/72730740?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

android9.0系统下,讨论如何延长APP退到后台的保活/复活时间

一、7.0及以上不存在真正意义的保活。

二、盘点目前在9.0上,可能有效的“白色手段”保活手段(这里不讨论黑色和灰色手段)。

1.仿TIM引导用户打开“后台自启动”和加入“手机白名单”

测试开始后台自启动,测试通知栏多久还能收到通知

华为M10 9.0

时长3到5小时没被杀死

VIVO x23 9.0(数字以分钟计算)

1 Y收到

2 Y

3 Y

6 Y

8 通知栏已无通知(app被系统杀死)

10 N收不到

抛出问题:使用H5界面引导用户打开后台自启动,用户如果会同意吗?

2.开启前台服务,会生成多余的通知,被产品否定

3.优化应用内存,正在进行中...

4.仿网易云音乐,复写锁屏界面

5.集成华为/小米/oppo/vivo/魅族手机系统级推送

6.集成“信鸽/个推/极光/友盟等”第三方推送,以期达到关联启动。

三、盘点已经失效或者不适合的保活黑科技,这里的“不适合”是因为我们做政府项目,后台是布在内网上的。

1.双进程守护方案,华为6.0就失效

2.监听锁屏/亮屏/解锁广播,打开1像素Activity,华为6.0就失效,因广播被取消了

3.故意在后台播放无声的音乐,华为M10手机9.0失效

4.使用JobScheduler唤醒Service,7.0以上失效

5.集成华为/小米/oppo/vivo/魅族等push,因为项目本地化部署,不适合

6.推送互相唤醒复活:极光、友盟、以及各大厂商的推送,因为项目本地化部署,不适合

7.同派系APP广播互相唤醒:比如今日头条系、阿里系,因为项目本地化部署,不适合

8.使用自定义锁屏界面:覆盖了系统锁屏界面。网易云音乐就是如此,但是会生成一个常驻通知栏的通知

9.把APP设置为系统应用,不适合,因为需要权限等

10.native进程(已报废)

11.利用账号同步机制拉活,失效了

12. 提高Service优先级,比如onStartCommand返回START_STICKY,没什么效果

Android 2020年最新保活方案 保活90% 已适配8.0 ,9.0, 10.0(酷狗音乐)相关推荐

  1. Android获取酷狗音乐歌曲详情

    Android获取酷狗音乐歌曲详情 一.目标 二.失效的实现方式 三.可用的实现方式 四.参考资料 五.写在最后 一.目标 酷狗音乐歌曲详情包括以下信息. 字段 描述 title 标题,即歌曲名称 a ...

  2. Android获取酷狗音乐歌曲详细信息

    Android获取酷狗音乐歌曲详细信息 一.目标 二.实现方案 三.最终方案 四.网易云音乐 五.遗留问题 六.接下来 七.Finally 在<Android获取歌曲详细信息>一文中,介绍 ...

  3. android 酷狗demo_酷狗音乐Android客户端详细使用评测

    曾经现在酷狗音乐一直是PC机上必装的音乐播放软件,手机音乐播放器哪个好用呢,酷狗音乐Android客户端也经过几个版本更新,版酷狗音乐的功能,界面都趋于完美.下面来看看酷狗音乐Android客户端详细 ...

  4. 酷狗android平板,安卓平板车载共享 体验酷狗音乐HD版

    安卓平板车载共享 体验酷狗音乐HD版 2013年04月24日 13:53作者:马承平编辑:马承平文章出处:泡泡网原创 分享 泡泡网影音相关频道4月24日 自苹果iPad及各品牌Android平板面世以 ...

  5. android酷狗界面,酷狗音乐Android 2.2版系统优化版界面曝光

    酷狗音乐Android 2.2版系统优化版界面曝光 2011-03-23 13:30:13  来源:cnbeta 扫码可以: 1.在手机上浏览 2.分享给微信好友或朋友圈 摘要: 酷狗音乐也针对And ...

  6. android 酷狗demo_酷狗音乐(Android)v8.1.5去广告清爽版

    本帖最后由 三生三世 于 2016-7-11 10:56 编辑 酷狗音乐安卓版更新至v8.1.5版.酷狗音乐(Android)是迄今为止最强大,最多人使用的音乐软件!有强大的音乐搜索,高速下载,海量曲 ...

  7. Android QQ音乐/酷狗音乐锁屏控制实现原理,酷狗锁屏

    混乱的锁屏控制 Android自4.0版本, 也就是API level 14开始, 加入了锁屏控制的功能, 相关的类是RemoteControlClient, 这个类在API level 21中被标记 ...

  8. Android版酷狗音乐 v9.0.1 去广告SVIP珍藏V2版

    by YYY~清羽 ◎兼容最新版MIUI系统 ◎去除启动页,首页,专辑页,听歌识曲页广告 ◎去除多余权限,服务,广播接收器,内容提供商 ◎去除安卓8以上系统的"正在运行通知" ◎去 ...

  9. 使用android studio时酷狗音乐,17 Android Studio开发实战:音乐播放器——浪花音乐...

    手机上的多媒体内容讲究声情并茂.悦目且悦耳,这样才能让用户的感官得到最大享受.影视播放器由于存在视频自身的画面,反而限制了开发者的施展空间:而音乐播放器允许定制播放画面,开发者有足够空间施展拳脚.本节 ...

  10. Android插件化开发指南——实践之仿酷狗音乐首页

    文章目录 1. 前言 2. 布局分析 3. 底部导航栏的实现 4. 顶部导航栏和ViewPager+Fragment的关联 1. 前言 在Android插件化开发指南--2.15 实现一个音乐播放器A ...

最新文章

  1. python使用matplotlib可视化函数曲线、设置y轴为对数坐标(log scale)、默认情况下坐标轴为线性坐标
  2. VIM编辑器(第十章)
  3. 汇编语言随笔(1)- 初步介绍和寄存器概览
  4. GitHub 实现多人协同提交代码并且权限分组管理
  5. Codeforces Round #FF (Div. 1) A. DZY Loves Sequences
  6. java 压缩 乱码_如何解决java压缩文件乱码问题
  7. 奖金(信息学奥赛一本通-T1352)
  8. python中import问题
  9. Cesium加载GeoServer发布的SHP和GeoTIFF文件
  10. 学习EXT第八天:EXT的布局(Layout)Part 1
  11. XeCJK 使用系统字体
  12. wx2540h配置教程_H3C无线AP控制器EWP-WX2540H 无线AP 无线云台控制器 无线控制器
  13. STM32f107 CAN滤波器设置
  14. PCIE--1--概念认知
  15. SQL 发送Email
  16. 二分类最优阈值确定_一文搞懂分类算法中常用的评估指标
  17. 计算机专业选择福大还是南邮,48所院校考研历年报录比汇总,21考研可参考!...
  18. UnhandledPromiseRejectionWarning: MongoError: command insert requir es authentication
  19. Anno六轴机械臂solidworks转urdf
  20. mysql8.0.19中在navicat客户端中int、bigint等类型设置长度保存后为0

热门文章

  1. 使用JS监听键盘按下事件
  2. Unity按钮按下、抬起的反应
  3. 属于计算机语言基本元素是,高级编程语言的共有的一些基本要素
  4. 推荐个边玩边学编程的游戏
  5. VC6中如何让改变控件Botton的字体(大小和字体)
  6. 特此感谢!酷睿12、希捷硬盘、机械键盘……免费送大家
  7. OPenCV3.2 图像反差的两种方法
  8. 推荐系统序列化建模总结
  9. steam的游戏服务器在哪个文件夹,使用SteamCMD在Windows上架设Don't Starve Together服务器...
  10. 推荐两款个人深度使用的笔记软件