Android进程保活(常驻内存)

Android将进程分为6个等级,它们按优先级顺序由高到低依次是:
 1.前台进程( FOREGROUND_APP);
 2.可视进程(VISIBLE_APP );
 3. 次要服务进程(SECONDARY_SERVER );
 4.后台进程 (HIDDEN_APP);
 5.内容供应节点(CONTENT_PROVIDER);
 6.空进程(EMPTY_APP);

Android后台杀死系列之一:FragmentActivity及PhoneWindow后台杀死处理机制- https://www.jianshu.com/p/00fef8872b68
Android后台杀死系列之二:ActivityManagerService与App现场恢复机制- https://www.jianshu.com/p/e3612a9b1af3
  Android后台杀死恢复原理:Application进程被Kill,但现场被AMS保存,AMS能根据保存恢复Application现场。
Android后台杀死系列之三:LowMemoryKiller原理(4.3-6.0)- https://www.jianshu.com/p/23cf3199f606
  被动扫描,找到低优先级的进程,杀死。
Android APP进程是有优先级的的,与进程是否被用户感知有直接关系;
APP切换等活动都可能造成进程优先级的变化,都是利用AMS,并通过proc文件设置到内核的;
LowmemoryKiller运行在内核,在内存需要缩减的时候,会选择低优先级的进程杀死。
  保活策略:前台通知;Daemon守护线程,提高线程优先级;微信的保活方案:双Service强制前台进程保活。提高进程的优先级;前后台Service;前台一像素的Activity;厂商推送渠道等;账号同步,Jobscheduler,相互唤醒,系统服务捆绑。
-- App保活方案A lite library, you can make your project depend it easily, and your project will be UNDEAD (contains
api from 9 to 23, lol).- https://github.com/Marswin/MarsDaemon
 Android应用保活方案的另类出路- https://blog.csdn.net/jiangwei0910410003/article/details/82558465

> 进程保活
 进程保活的关键点有两个,一个是进程优先级的理解,优先级越高存活几率越大。二是弄清楚哪些场景会导致进程会kill,然后采取下面的策略对各种场景进行优化:
1.提高进程的优先级; 2.在进程被kill之后能够唤醒;

-- 进程保活:
4.0-5.0:双进程保活(5.0上有进程组,主进程被杀死,其他进程不能幸免)
5.0-6.0:JobScheduler
6.0-   : JNI双进程守护,Android6.0的JobService;

-- Low Memory Killer的原理: http://www.cnblogs.com/angeldevil/archive/2013/05/21/3090872.html
因为 LMK 机制的存在,虽然 App 允许在后台运行,但同样也面临随时被清理的风险。因此,我们需要在被清理后及时的重新启动。常规的,有 4 种方式能够做到:
  1.sticky service,就是在 Service 的 onStartCommand 中返回 sticky flag,这样当 service 被 kill 掉后,系统会将它加入重启的 pending 列表,在后面合适的时机再把 service 重启;
  2.alarm,闹钟,有循环闹钟和一次性闹钟两种,在闹钟触发后启动对应的组件;
  3.在 Manifest 文件中静态注册的 Receiver,通过监听各种系统事件,比如开机、网络变化、mount/unmounts 等。在这些事件发生时启动组件,因为这种方式会造成在这些事件发生时系统容易卡顿,在7.0里面,Android增加了限制;
  4.JobScheduler,这是在 5.0 里面新增的,允许 App 在特定事件发生时做一些动作,比如充电、切换到 Wi-Fi 等。

android进程保活实践- https://www.jianshu.com/p/53c4d8303e19
进程保活-https://github.com/08carmelo/android-keeplive
微信Android客户端后台保活经验分享- http://mt.sohu.com/20160408/n443685317.shtml 
APP保活AndroidDaemonService- https://github.com/D-clock/AndroidDaemonService
APP保活KeepingAppAlive- https://github.com/jiangdongguo/KeepingAppAlive

Android进程保活招式大全 -- http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8
关于 Android 进程保活,你所需要知道的一切- http://blog.csdn.net/f2006116/article/details/51188228
APP中一种在Java层实现的简单守护进程方式- https://blog.csdn.net/hejjunlin/article/details/52779986
探讨一种新型的双进程守护应用保活- http://blog.csdn.net/andrexpert/article/details/53485360
探讨Android6.0及以上系统APP常驻内存(保活)实现-争宠篇- http://blog.csdn.net/andrexpert/article/details/75045678#comments
探讨Android6.0及以上系统APP常驻内存(保活)实现-复活篇- http://blog.csdn.net/andrexpert/article/details/75174586
Android进程保活的一般套路- http://www.apkbus.com/blog-719059-63191.html
Android进程保活: http://www.oschina.net/news/72685/android-process?p=2
Android service后台保活原理相关和测试结果-http://blog.csdn.net/pvlking/article/details/50503803
Android进程保活总结- http://blog.csdn.net/superxlcr/article/details/70244803

2018年Android的保活方案效果统计- https://www.jianshu.com/p/b5371df6d7cb

Android 进程保活招式大全- http://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=2653577617&idx=1&sn=623256a2ff94641036a6c9eea17baab8&scene=0#wechat_redirect

-- 通过JNI实现守护进程,每1s的轮训会消耗系统大量资源;没什么作用
  如何fork一个进程 Android  ,通过JNI在native层去fork一个进程也可以
Android 通过JNI实现守护进程,使Service服务不被杀死-- http://blog.csdn.net/yyh352091626/article/details/50542554
Android 通过JNI实现双守护进程,保证服务不被杀死 源码-- http://download.csdn.net/detail/yyh352091626/9410153
Android 通过JNI实现守护进程- https://blog.csdn.net/yyh352091626/article/details/50542554
Android 通过JNI实现守护进程- https://github.com/dearHaoGeGe/DaemonProcess
Android中用jni实现的守护进程- https://github.com/CharonChui/DaemonService
APP中一种在Java层实现的简单守护进程方式- https://github.com/hejunlin2013/MultiMediaSample
Android进程守护详解及解决方案- http://blog.csdn.net/lanye11/article/details/53156752
Android SERVICE后台服务进程的守护- https://github.com/Marswin/MarsDaemon  http://blog.csdn.net/t12x3456/article/details/8982198
Android双进程守护- http://blog.csdn.net/wds1181977/article/details/51028537
Android 通过JNI实现守护进程,使得Service服务不被杀死- http://blog.csdn.net/lwyygydx/article/details/50716182

> Android后台进程保活之黑科技,from天猫技术:http://blog.csdn.net/theone10211024/article/details/51547698
  android进程的存活率: 常见的方法有setforeground或是采取守护进程。
  对于采取守护进程,做起来比麻烦,做法上比较流氓,而采用setforeground,似乎不可避免的会在通知栏显示一个通知。
  进程数字越小,优先级越高,越不容易被杀死。
  这里说几个标准,-16是系统进程,0是前台进程,这里的前台进程是指用户正在使用的Activity所在的进程,用户按Home键之后回到桌面时的优先级是6,普通Service的进程是8.

> 进程保活手段主要分为 黑、白、灰 三种
-- 当前业界的Android进程保活手段主要分为 黑、白、灰 三种,其大致的实现思路如下:
 1.白色保活:启动前台Service;白~直接按照系统那样,生成前台service,在notification栏可见到一天bar横在那里,这种是系统提供的合法保活方式。
 2.灰色保活:利用系统的漏洞启动前台Service;灰~在白的方式上,利用系统漏洞开启前台service,但是不会在N栏上出现一条bar,这个bug在Android4.3后已经被Google修复。
 3.黑色保活:不同的app进程,用广播相互唤醒(包括利用系统提供的广播进行唤醒);黑,最无耻的方式,拉帮结派。例如百度全家桶那样,一人得道,全家开启。。。呵呵哒,我不会告诉你像,微信这样的应用在我的手机见面有二三十条唤醒路径。。其他脉脉,小米,陌陌之类的APP也都不是神马善类,同样几十条唤醒路径。所以,你就可以知道为什么Android机子会慢慢卡成一坨翔,这他妈没root过的手机开个bat系的APP,能把你一大堆APP在后台给你搞活了).

  所谓黑色保活,就是利用不同的app进程使用广播来进行相互唤醒。举个3个比较常见的场景:
 场景1:开机,网络切换、拍照、拍视频时候,利用系统产生的广播唤醒app
 场景2:接入第三方SDK也会唤醒相应的app进程,如微信sdk会唤醒微信,支付宝sdk会唤醒支付宝。由此发散开去,就会直接触发了下面的 场景3
 场景3:假如你手机里装了支付宝、淘宝、天猫、UC等阿里系的app,那么你打开任意一个阿里系的app后,有可能就顺便把其他阿里系的app给唤醒了。(只是拿阿里打个比方,其实BAT系都差不多),Android手机就是一步一步的被上面这些场景给拖卡机的。

  白色保活手段非常简单,就是调用系统api启动一个前台的Service进程,这样会在系统的通知栏生成一个Notification,用来让用户知道有这样一个app在运行着,哪怕当前的app退到了后台。

  灰色保活,这种保活手段是应用范围最广泛。它是利用系统的漏洞来启动一个前台的Service进程,与普通的启动方式区别在于,它不会在系统通知栏处出现一个Notification,看起来就如同运行着一个后台Service进程一样。这样做带来的好处就是,用户无法察觉到你运行着一个前台进程(因为看不到Notification),但你的进程优先级又是高于普通后台进程的。那么如何利用系统的漏洞呢,大致的实现思路和代码如下:
  思路一: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.Service设置成START_STICKY,kill 后会被重启(等待5秒左右),重传Intent,保持与重启前一样
    ​通过 startForeground将进程设置为前台进程,做前台服务,优先级和前台应用一个级别​,除非在系统内存非常缺,否则此进程不会被 kill
 2.双进程Service:让2个进程互相保护,其中一个Service被清理后,另外没被清理的进程可以立即重启进程
 3.QQ黑科技:在应用退到后台后,另起一个只有 1 像素的页面停留在桌面上,让自己保持前台状态,保护自己不被后台清理工具杀死
 4.在已经root的设备下,修改相应的权限文件,将App伪装成系统级的应用(Android4.0系列的一个漏洞,已经确认可行)
 5.Android系统中当前进程(Process)fork出来的子进程,被系统认为是两个不同的进程。当父进程被杀死的时候,子进程仍然可以存活,并不受影响。鉴于目前提到的在Android-Service层做双守护都会失败,我们可以fork出c进程,多进程守护。死循环在那检查是否还存在,具体的思路如下:(Android5.0以下可行)
    用C编写守护进程(即子进程),守护进程做的事情就是循环检查目标进程是否存在,不存在则启动它。
    在NDK环境中将1中编写的C代码编译打包成可执行文件(BUILD_EXECUTABLE)。
    主进程启动时将守护进程放入私有目录下,赋予可执行权限,启动它即可。
 6.联系厂商,加入白名单;Github还出现了一个很火的“黑科技”进程保活库,声称可以做到进程永生不死。https://github.com/D-clock/AndroidDaemonService
 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 11 中,要让服务常驻内存,可以通过使用前台服务(Foreground Service)实现。前台服务是一种特殊的服务类型,可以将服务标记为正在运行的重要服务,以便系统知道它们需要更多的资源(例如内存),从而更不可能被系统杀死。 要创建前台服务,您需要在服务的 onStartCommand() 方法中调用 startForeground() 方法,并传递一个 Notification 对象。该 Notification 对象将显示在系统状态栏中,并告知用户该服务正在运行。如果您需要更新通知内容,可以调用 NotificationManager 的 startForeground() 方法,传递一个更新后的 Notification 对象。 需要注意的是,在前台服务不再需要时,应该及时调用 stopForeground() 方法,以便将服务降为后台服务,释放资源。 下面是一个前台服务的示例代码: ``` public class MyForegroundService extends Service { private static final int NOTIFICATION_ID = 1; @Override public int onStartCommand(Intent intent, int flags, int startId) { Notification notification = createNotification(); startForeground(NOTIFICATION_ID, notification); // do some work here return START_STICKY; } private Notification createNotification() { NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("My Foreground Service") .setContentText("Service is running...") .setSmallIcon(R.drawable.ic_notification); return builder.build(); } @Override public void onDestroy() { super.onDestroy(); stopForeground(true); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } } ``` 在此示例中,创建了一个名为 MyForegroundService 的前台服务。在 onStartCommand() 方法中调用了 startForeground() 方法,并传递了一个 Notification 对象,该对象显示了服务正在运行的信息。在 onDestroy() 方法中,调用了 stopForeground() 方法,以便将服务降为后台服务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值