• 安卓


    https://www.cnblogs.com/AndroidJotting/p/4943809.html  通过bind 调用

    Android 进程保活,Service进程常驻

    关于 Android 平台的进程保活这一块,想必是所有 Android 开发者瞩目的内容之一。你到网上搜 Android 进程保活,可以搜出各种各样神乎其技的做法,绝大多数都是极其不靠谱。前段时间,Github还出现了一个很火的“黑科技”进程保活库,声称可以做到进程永生不死。
    CSDN上也出现过一篇使用C进程守护的方式,Android进程常驻:
    
    • 1
    • 2

    http://blog.csdn.net/marswin89/article/details/50917098

    ,也能很好的解决5.0及以下的机器。 
    接下来本文讲的内容是来至:

    http://www.open-open.com/lib/view/open1460895212779.html

    主要讲灰色保活。
    灰色保活,这种保活手段是应用范围最广泛。它是利用系统的漏洞来启动一个前台的Service进程,与普通的启动方式区别在于,它不会在系统通知栏处出现一个Notification,看起来就如同运行着一个后台Service进程一样。这样做带来的好处就是,用户无法察觉到你运行着一个前台进程(因为看不到Notification),但你的进程优先级又是高于普通后台进程的。那么如何利用系统的漏洞呢,大致的实现思路和代码如下:
    
    • 1
    • 2

    思路一:API < 18,启动前台Service时直接传入new Notification(); 
    思路二:API >= 18,同时启动两个id相同的前台Service,然后再将后启动的Service做stop处理;

    public class GrayService extends Service {
    
        private final static int GRAY_SERVICE_ID = 1001;
    
        @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());
            }
    
            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);
            }
    
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    这样能让你神不知鬼不觉的启动着一个前台Service。我们可以使用adb命令行程序,在然后输入下面的shell命令这里写图片描述

    打印出指定包名的所有进程中的Service信息,看下有没有 isForeground=true 的关键信息。如果通知栏没有看到属于app的 Notification 且又看到 isForeground=true 则说明了,此app利用了这种灰色保活的手段。当然这也只是目前一种可行的方式,哪天google封了也是有可能的。

    下面就给自己做个记录,记录下系统的进程回收机制 
    熟悉Android系统的童鞋都知道,系统出于体验和性能上的考虑,app在退到后台时系统并不会真正的kill掉这个进程,而是将其缓存起来。打开的应用越多,后台缓存的进程也越多。在系统内存不足的情况下,系统开始依据自身的一套进程回收机制来判断要kill掉哪些进程,以腾出内存来供给需要的app。这套杀进程回收内存的机制就叫 Low Memory Killer ,它是基于Linux内核的 OOM Killer(Out-Of-Memory killer)机制诞生。

    了解完 Low Memory Killer,再科普一下oom_adj。什么是oom_adj?它是linux内核分配给每个系统进程的一个值,代表进程的优先级,进程回收机制就是根据这个优先级来决定是否进行回收。对于oom_adj的作用,你只需要记住以下几点即可:

    进程的oom_adj越大,表示此进程优先级越低,越容易被杀回收;越小,表示进程优先级越高,越不容易被杀回收 
    普通app进程的oom_adj>=0,系统进程的oom_adj才可能<0 
    那么我们如何查看进程的oom_adj值呢,需要用到下面的两个shell命令

    ps | grep PackageName //获取你指定的进程信息 
    这里写图片描述

    关于 Android 进程保活,你所需要知道的一切

    这里是以我写的demo代码为例子,红色圈中部分别为下面三个进程的ID

    UI进程:com.clock.daemon 
    普通后台进程:com.clock.daemon:bg 
    灰色保活进程:com.clock.daemon:gray

    当然,这些进程的id也可以通过AndroidStudio获得

    这里写图片描述

    接着我们来再来获取三个进程的oom_adj

    cat /proc/进程ID/oom_adj

    这里写图片描述

    从上图可以看到UI进程和灰色保活Service进程的oom_adj=0,而普通后台进程oom_adj=15。到这里估计你也能明白,为什么普通的后台进程容易被回收,而前台进程则不容易被回收了吧。但明白这个还不够,接着看下图

    这里写图片描述

    上面是我把app切换到后台,再进行一次oom_adj的检验,你会发现UI进程的值从0变成了6,而灰色保活的Service进程则从0变成了1。这里可以观察到,app退到后台时,其所有的进程优先级都会降低。但是UI进程是降低最为明显的,因为它占用的内存资源最多,系统内存不足的时候肯定优先杀这些占用内存高的进程来腾出资源。所以,为了尽量避免后台UI进程被杀,需要尽可能的释放一些不用的资源,尤其是图片、音视频之类的。

    从Android官方文档中,我们也能看到优先级从高到低列出了这些不同类型的进程:Foreground process、Visible process、Service process、Background process、Empty process。而这些进程的oom_adj分别是多少,又是如何挂钩起来的呢?推荐大家阅读下面这篇文章:

    http://www.cnblogs.com/angeldevil/archive/2013/05/21/3090872.html

    总结(文末有福利) 
    絮絮叨叨写完了这么多,最后来做个小小的总结。回归到开篇提到QQ进程不死的问题,我也曾认为存在这样一种技术。可惜我把手机root后,杀掉QQ进程之后就再也起不来了。有些手机厂商把这些知名的app放入了自己的白名单中,保证了进程不死来提高用户体验(如微信、QQ、陌陌都在小米的白名单中)。如果从白名单中移除,他们终究还是和普通app一样躲避不了被杀的命运,为了尽量避免被杀,还是老老实实去做好优化工作吧。

    所以,进程保活的根本方案终究还是回到了性能优化上,进程永生不死终究是个彻头彻尾的伪命题!

  • 相关阅读:
    单机 Nexus 部署
    Docker 部署 3 节点 ES 集群
    Harbor 高可用部署
    Python 第四次实验
    es入门
    Golang的Test的用法
    spring elastic
    golang下载包的时候出现 dial tcp 142.251.43.17:443: i/o timeout时候解决
    Java加密并压缩文件
    feign调用添加header
  • 原文地址:https://www.cnblogs.com/vana/p/10966440.html
Copyright © 2020-2023  润新知