
正文
android保活,android保活第三方框架
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
Android中的保活机制
Android中的保活是一个永不过时的话题,因为每一个APP都希望能在后台不停的运行去搜集用户数据,在Android 系统处于较低版本的时候(目前最新版本为12,较低版本指的是8以下),很多APP借助于系统层面的漏洞研发出了各种保活的方法,但是随着Android 版本的不断更新,过往的保活方法渐渐失效,Android中的保活成为了一个越来越难办到的事情,但是我认为这是一个好事,如非这样你永远不知道你的手机后台到底有多少APP背着你干了多少事情。当然,系统的事情不是我们能掌控的了的。那么,我们先来看看以前为了保活都有哪些手段。
手段一:在Service的onStartCommand方法中返回****START_STICKY****(****亲测无效****)
在Service的onStartCommand方法中返回键有下面几种可供选择:
(1)START_STICKY:如果Service所在的进程,在执行了onStartCommand方法后,被清理了,那么这个Service会被保留在已开始的状态,但是不保留传入的Intent,随后系统会尝试重新创建此Service。
(2)START_NOT_STICKY:如果Service所在的进程,在执行了onStartCommand方法后,被清理了,则系统不会重新启动此Service。
(3)START_REDELIVER_INTENT:如果Service所在的进程,在执行了onStartCommand方法后,被清理了,则结果和START_STICKY一样,也会重新创建此Service并调用onStartCommand方法。不同之处在于,如果是返回的是START_REDELIVER_INTENT ,则重新创建Service时onStartCommand方法会传入之前的intent。
手段二:在清单文件里面设置优先级****(****亲测无效****)
手段三:在Service即将销毁的时候重新启动****(****亲测无效****)
手段四:借助AIDL使用双进程保活****(****亲测无效****)
首先创建一个AIDL文件
创建本地服务
创建远程服务:
最后在清单文件声明:
手段五:1像素的Activity让应用在熄屏后保活****(****亲测无效****)
具体怎么实现可以参照这篇文章
u;/u
运行一段时间后系统会自动杀死整个APP
手段六:****开启前台服务(亲测有效)
在Service的onCreate方法中开启前台服务
当然,APP保活的方式方法远不止这些,但是随着Android 系统的不断优化,保活现在越来越不太现实,但是我们可以尽量提高我们APP的优先级让系统不轻易杀死我们的APP,这一点还是可以办到的。
相关问答
Q1: Android 如何进行进程保活
每一个 Android 应用启动后至少对应一个进程,有的是多个进程,而且主流应用中多个
进程的应用比例较大
对于任何一个进程,我们都可以通过 adb shell ps|grep package_name的方式来查看
它的基本信息
Android 中的进程跟封建社会一样,分了三流九等,Android 系统把进程的划为了如下
几种(重要性从高到低),网上多位大神都详细总结过(备注:严格来说是划分了 6 种)。
场景:
1.某个进程持有一个正在与用户交互的 Activity 并且该 Activity 正处于 resume 的
状态。
2.某个进程持有一个 Service,并且该 Service 与用户正在交互的 Activity 绑定。
3.某个进程持有一个 Service,并且该 Service 调用 startForeground()方法使之位于前台运行。
4.某个进程持有一个 Service,并且该 Service 正在执行它的某个生命周期回调方法,比如 onCreate()、 onStart()或 onDestroy()。
5.某个进程持有一个 BroadcastReceiver,并且该 BroadcastReceiver 正在执行其onReceive()方法。用户正在使用的程序,一般系统是不会杀死前台进程的,除非用户强制停止应用或者系统内存不足等极端情况会杀死。
场景:
1.拥有不在前台、但仍对用户可见的 Activity(已调用 onPause())。
2.拥有绑定到可见(或前台)Activity 的 Service
用户正在使用,看得到,但是摸不着,没有覆盖到整个屏幕,只有屏幕的一部分可见进程
不包含任何前台组件,一般系统也是不会杀死可见进程的,除非要在资源吃紧的情况下,
要保持某个或多个前台进程存活
场景
1.某个进程中运行着一个 Service 且该 Service 是通过 startService()启动的,与用户看见的界面没有直接关联。
在内存不足以维持所有前台进程和可见进程同时运行的情况下,服务进程会被杀死
场景:
在用户按了"back"或者"home"后,程序本身看不到了,但是其实还在运行的程序,
比如 Activity 调用了 onPause 方法系统可能随时终止它们,回收内存
场景:
某个进程不包含任何活跃的组件时该进程就会被置为空进程,完全没用,杀了它只有好处没坏处,第一个干它!
上面是进程的分类,进程是怎么被杀的呢?系统出于体验和性能上的考虑,app 在退到
后台时系统并不会真正的 kill 掉这个进程,而是将其缓存起来。打开的应用越多,后台缓存的进程也越多。在系统内存不足的情况下,系统开始依据自身的一套进程回收机制
来判断要 kill 掉哪些进程,以腾出内存来供给需要的 app, 这套杀进程回收内存的机制
就叫 Low Memory Killer。那这个不足怎么来规定呢,那就是内存阈值,我们可以使用
cat /sys/module/lowmemorykiller/parameters/minfree 来查看某个手机的内存阈值。
其实系统在进程回收跟内存回收类似也是有一套严格的策略,可以
自己去了解,大概是这个样子的,oom_adj 越大,占用物理内存越多会被最先 kill 掉,OK,那么现在对于进程如何保活这个问题就转化成,如何降低 oom_adj 的值,以及如
何使得我们应用占的内存最少。
据说这个是手 Q 的进程保活方案,基本思想,系统一般是不会杀死前台进程的。所以要
使得进程常驻,我们只需要在锁屏的时候在本进程开启一个 Activity,为了欺骗用户,
让这个 Activity 的大小是 1 像素,并且透明无切换动画,在开屏幕的时候,把这个 Activity
关闭掉,所以这个就需要监听系统锁屏广播,我试过了,的确好使,如下。
如果直接启动一个 Activity,当我们按下 back 键返回桌面的时候,oom_adj 的值是 8,
上面已经提到过,这个进程在资源不够的情况下是容易被回收的。现在造一个一个像素
的 Activity。
为了做的更隐藏,最好设置一下这个 Activity 的主题,当然也无所谓了
在屏幕关闭的时候把 LiveActivity 启动起来,在开屏的时候把 LiveActivity 关闭掉,所以
要监听系统锁屏广播,以接口的形式通知 MainActivity 启动或者关闭 LiveActivity。
现在 MainActivity 改成如下
按下 back 之后,进行锁屏,现在测试一下 oom_adj 的值
果然将进程的优先级提高了。
但是还有一个问题,内存也是一个考虑的因素,内存越多会被最先 kill 掉,所以把上面
的业务逻辑放到 Service 中,而 Service 是在另外一个 进程中,在 MainActivity 开启这
个服务就行了,这样这个进程就更加的轻量,
OK,通过上面的操作,我们的应用就始终和前台进程是一样的优先级了,为了省电,
系统检测到锁屏事件后一段时间内会杀死后台进程,如果采取这种方案,就可以避免了
这个问题。但是还是有被杀掉的可能,所以我们还需要做双进程守护,关于双进程守护,
比较适合的就是 aidl 的那种方式,但是这个不是完全的靠谱,原理是 A 进程死的时候,
B 还在活着,B 可以将 A 进程拉起来,反之,B 进程死的时候,A 还活着,A 可以将 B
拉起来。所以双进程守护的前提是,系统杀进程只能一个个的去杀,如果一次性杀两个,
这种方法也是不 OK 的。
事实上
那么我们先来看看 Android5.0 以下的源码,ActivityManagerService 是如何关闭在应用
退出后清理内存的
在应用退出后,ActivityManagerService 不仅把主进程给杀死,另外把主进程所属的进
程组一并杀死,这样一来,由于子进程和主进程在同一进程组,子进程在做的事情,也
就停止了。所以在 Android5.0 以后的手机应用在进程被杀死后,要采用其他方案。
这种大部分人都了解,据说这个微信也用过的进程保活方案,移步微信 Android 客户端
后台保活经验分享,这方案实际利用了 Android 前台 service 的漏洞。
原理如下
对于 API level 18 :调用 startForeground(ID, new Notification()),发送空的
Notification ,图标则不会显示。
对于 API level = 18:在需要提优先级的 service A 启动一个 InnerService,两个服务
同时 startForeground,且绑定同样的 ID。Stop 掉 InnerService ,这样通知栏图标即
被移除。
public class KeepLiveService extends Service{
public static final int NOTIFICATION_ID=0x11;
public KeepLiveService() {
}
@Override
public IBinder onBind(Intent intent){
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate(); //API 18 以下,直 接发 送 Notification 并 将 其 置 为 前 台
if(Build.VERSION.SDK_INTBuild.VERSION_CODES.JELLY_BEAN_MR2){
startForeground(NOTIFICATION_ID,new Notification());
} else { //API 18 以上,发送 Notification 并将其置为前台后,启动 InnerService
Notification.Builder builder=new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
startForeground(NOTIFICATION_ID, builder.build());
startService(new Intent(this, InnerService.class));
}
}
public class InnerService extends Service{
@Override public IBinder onBind(Intent intent) {
return null;
}
@Override public void onCreate() {
super.onCreate(); //发送与 KeepLiveService中 ID 相同的 Notification,然后将其取消并取消自己的前台显示
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);startForeground(NOTIFICATION_ID,
builder.build());
new Handler().postDelayed(new Runnable() {
@Override public void run() {
stopForeground(true);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(NOTIFICATION_ID);
stopSelf();
}
},
100);
}
}
}
在没有采取前台服务之前,启动应用,oom_adj 值是 0,按下返回键之后,变成 9(不
同 ROM 可能不一样)
相互唤醒的意思就是,假如你手机里装了支付宝、淘宝、天猫、UC 等阿里系的 app,
那么你打开任意一个阿里系的 app 后,有可能就顺便把其他阿里系的 app 给唤醒了。
这个完全有可能的。此外,开机,网络切换、拍照、拍视频时候,利用系统产生的广播
也能唤醒 app,不过 Android N 已经将这三种广播取消了。
如果应用想保活,要是 QQ,微信愿意救你也行,有多少手机上没有 QQ,微信呢?或
者像友盟,信鸽这种推送 SDK,也存在唤醒 app 的功能。
拉活方法
JobSheduler是作为进程死后复活的一种手段,
native进程方式最大缺点是费电,Native
进程费电的原因是感知主进程是否存活有两种实现方式,在 Native 进程中通过死循环
或定时器,轮训判断主进程是否存活,当主进程不存活时进行拉活。其次 5.0 以上系统
不支持。 但是 JobSheduler 可以替代在 Android5.0 以上 native 进程方式,这种方式即
使用户强制关闭,也能被拉起来,亲测可行。
JobSheduler@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class MyJobService extends JobService {
@Override
public void onCreate() {
super.onCreate();
startJobSheduler();
}
public void startJobSheduler() {
try {
JobInfo.Builder builder = new JobInfo.Builder(1,new ComponentName(getPackageName(), MyJobService.class.getName()));
builder.setPeriodic(5); builder.setPersisted(true); JobScheduler jobScheduler =(JobScheduler)
this.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(builder.build());
}
catch
(Exception ex)
{ ex.printStackTrace(); } }
@Override
public boolean onStartJob(JobParameters jobParameters) {
return false;
} @Override public boolean onStopJob(JobParameters jobParameters) {
return false;
}
}
这个是系统自带的,onStartCommand 方法必须具有一个整形的返回值,这个整形的返
回值用来告诉系统在服务启动完毕后,如果被 Kill,系统将如何操作,这种方案虽然可
以,但是在某些情况 or 某些定制 ROM 上可能失效,我认为可以多做一种保保守方案。
1.START_STICKY
如果系统在 onStartCommand 返回后被销毁,系统将会重新创建服务并依次调用
onCreate 和 onStartCommand(注意:根据测试 Android2.3.3 以下版本只会调用
onCreate 根本不会调用 onStartCommand,Android4.0 可以办到),这种相当于服务
又重新启动恢复到之前的状态了)。
2.START_NOT_STICKY
如果系统在 onStartCommand 返回后被销毁,如果返回该值,则在执行完
onStartCommand 方法后如果 Service 被杀掉系统将不会重启该服务
3.START_REDELIVER_INTENT
START_STICKY 的兼容版本,不同的是其不保证服务被杀后一定能重启。
4.相比与粘性服务与系统服务捆绑更厉害一点,这个来自爱哥的研究,这里说的系统服务
很好理解,比如 NotificationListenerService,NotificationListenerService 就是一个监听
通知的服务,只要手机收到了通知,NotificationListenerService 都能监听到,即时用户
把进程杀死,也能重启,所以说要是把这个服务放到我们的进程之中,那么就可以呵呵
了
所以你的应用要是有消息推送的话,那么可以用这种方式去欺骗用户。
Q2: Android-保活
Low Memory Killer
打开的应用越多,后台缓存的进程也越多。因为系统出于体验和性能上的考虑,app在退到后台时系统并不会真正的kill掉这个进程,而是将其缓存起来。于是在系统内存不足的情况下,系统开始依据自身的一套进程回收机制来判断要kill掉哪些进程,以腾出内存来供给需要的app, 这套杀进程回收内存的机制就叫 Low Memory Killer。
进程的优先级(by:)
前台进程
用户正在使用的程序,一般系统是不会杀死前台进程的,除非用户强制停止应用或者系统内存不足等极端情况会杀死。
可见进程
用户正在使用,看得到,但是摸不着,没有覆盖到整个屏幕,只有屏幕的一部分可见进程不包含任何前台组件,一般系统也是不会杀死可见进程的,除非要在资源吃紧的情况下,要保持某个或多个前台进程存活施。
服务进程
在内存不足以维持所有前台进程和可见进程同时运行的情况下,服务进程会被杀死。
后台进程
系统可能随时终止它们,回收内存。
空进程
某个进程不包含任何活跃的组件时该进程就会被置为空进程,完全没用,杀了它只有好处没坏处,第一个干它。
内存阈值
内存阈值在不同的手机上不一样,一旦低于该值,Android便会杀死对应优先级的进程。一旦低于该值,Android便开始按逆序关闭进程。即优先级从最高的空进程开始,逆序关闭,直到内存足够。
如何判断进程的优先级?
通过 oom_adj 值,判断进程的优先级,不同手机的oom_adj 值可能不一样。
我们了解这个有什么用呢?PS:了解这个你才能想办法保证自己怎么不被杀掉。
网上的一些方案和自己认为有用的方案
1 开启一个像素Activity(伪前台进程)
在锁屏的时候在本进程开启一个Activity,为了欺骗用户,让这个Activity的大小是1像素,并且透明无切换动画,在开屏幕的时候,把这个Activity关闭掉,所以这个就需要监听系统锁屏广播。
我们的应用就始终和前台进程是一样的优先级了,为了省电,系统检测到锁屏事件后一段时间内会杀死后台进程,如果采取这种方案,就可以避免了这个问题,但是还是有被杀掉的可能。
Android5.0以下:
Process.killProcessQuiet(pid);
Android5.0以后:
Process.killProcessQuiet(app.pid);
Process.killProcessGroup(app.info.uid, app.pid);
应用退出后,ActivityManagerService不仅把主进程给杀死,另外把主进程所属的进程组一并杀死,这样一来,由于子进程和主进程在同一进程组,子进程在做的事情,也就停止了。
2 相互唤醒(广播唤醒)
相互唤醒的意思就是,假如你手机里装了支付宝、淘宝、天猫、UC等阿里系的app,那么你打开任意一个阿里系的app后,有可能就顺便把其他阿里系的app给唤醒了。这个完全有可能的。此外,开机,网络切换、拍照、拍视频时候,利用系统产生的广播也能唤醒app,不过Android N已经将这三种广播取消了。
3 JobSheduler机制保活(不推荐)
JobSheduler是作为进程死后复活的一种手段,native进程方式最大缺点是费电, Native 进程费电的原因是感知主进程是否存活有两种实现方式,在 Native 进程中通过死循环或定时器,判断主进程是否存活,当主进程不存活时进行拉活。其次5.0以上系统不支持。 但是JobSheduler可以替代在Android5.0以上native进程方式,这种方式即使用户强制关闭,部分厂商手机(如:华为)也能被拉起来,但AndroidN失效。
4 粘性服务与系统服务捆绑()
这个是系统自带的,onStartCommand方法必须具有一个整形的返回值,这个整形的返回值用来告诉系统在服务启动完毕后。Service的onStartCommand方法里返回 STATR_STICK,onDestory中start自启(准确的将算不上进程拉活,只能算service自启,force_stop后不能正常拉活)。
5 监听第三方app开放的静态广播(同2)
需要大量反编译app去找开放的静态广播,而且不保证长期有效,可能第三方开放广播在版本升级时改为私有广播,如果自己公司有多个app,可广播互相拉起。
6 NDK+Socket通过fork实现进程保活方案()
实现进程守护实际是守护app的主要服务,当app主进程被系统kill时,主要服务也会杀死,守护进程将其唤醒。
实现原理图:
进程保活方案调研结果
未能实现真正意义上的进程保活。
光从保活这一点来说,绑定一个像素activity和循环一个无声的声音这种方法比较好,但是对用户来说太流氓了,不推荐。 对于有硬性需求的,可以引导用户加入白名单。至于推送, 可以尝试集成多个推送方案,小米,华为等都有推送sdk,在对应手机上可以确保收到消息, 然后像百度这种是多app公用通道的,也就是手机中有一个使用百度推送的app被允许后台启动,就能让其他app收到推送。随着Android版本的不断更新及国内厂商对ROM的不断优化,如何最大可能的对进程保活,是Android一道需要长期学习/钻研的学问,也是Android开发者不得不面对的问题。
引援:
Q3: Android保活——蓝牙唤醒(主动kill掉也可唤醒)
项目需要后台保活,但无论怎么保活,只要用户主动kill掉,app依然是活不了。
发现了蓝牙唤醒这个方式,用户主动kill掉也可行。
Android 8.0开始提供了 startscan的方法,
public void startScan(ScanCallback callback)
public void startScan(ListScanFilter filters,ScanSettings settings,ScanCallback callback)
public int startScan(ListScanFilter filters,ScanSettings settings,PendingIntent callbackIntent)
第一个没有过滤条件,锁屏就停止扫描
第二个可以加过滤条件,锁屏不影响扫描
第三个的扫描结果由PendingIntent发送,即使app没有在运行,系统也可以扫描后唤醒app,这就是我们要的方法了。
PendingIntent是对Intent的封装,是满足某些条件或触发某些事件后才执行指定的行为,主要用于闹钟、通知、桌面部件。Android的四大组件之间通信用Intent,跨进程通信用PendingIntent。
Android 8.0 引进了Context.startForegroundService(),在系统创建服务后,应用需要在ANR发生前调用startForeground(int ,android.app.Notification),如果未及时调用该方法,系统将报ANR错误 。系统给前台服务的ANR时间是20秒。
用startScan蓝牙唤醒的原理是:app向系统订阅了扫描结果(预先加了过滤条件),当蓝牙连接断开的时候,设备就会发广播,这时系统就可以扫描到对应的广播,唤醒对应的service,这时想做什么操作就根据你的项目需要了。至于系统会为你扫描多久,这个还没测试。
(1)setScanMode有四个参数可以选 :
SCAN_MODE_BALANCED:在平衡电源模式下执行蓝牙LE扫描。返回扫描结果的速度能够很好地权衡扫描频率和功耗。
SCAN_MODE_LOW_LATENCY:扫描使用最高占空比。建议只在应用程序在前台运行时使用此模式。
SCAN_MODE_LOW_POWER:在低功耗模式下执行蓝牙LE扫描。这是默认的扫描模式,因为它消耗的能量最少。如果扫描应用程序不在前台,则强制执行此模式。
SCAN_MODE_OPPORTUNISTIC:一种特殊的蓝牙LE扫描模式。使用这种扫描模式的应用程序将被动地侦听其他扫描结果,而不启动BLE扫描本身
(2)settingBuilder.setMatchMode有两个参数可以选:
MATCH_MODE_AGGRESSIVE: 信号弱也会报告
MATCH_MODE_STICKY: 信号比较强和扫描到的次数比较多才会报告
(3)settingBuilder.setCallbackType也有其他参数可选,但适用的就一个
(4) ScanFilter 的过滤方法有几个,如下图,打勾的是测试了可行的,但只有第一个DeviceAddress有唯一性
Q4: Android保活系列之——双进程守护
近期跳槽到玩加电竞,加之英雄联盟云顶之弈排位模式的推出,导致个人精力有限没有时间和心情去写相关的博客。
在Context中提供了bindService的方法
绑定服务是客户端--服务器接口中的服务器。组件和服务进行绑定后,可以发送请求、接收响应、执行进程间通信(IPC)。这里的服务器模型不同于网络C-S模型而是针对于Android应用不同的功能进行进程划分,例如提供视频播放的进程我们可以把它当做视频播放服务器,我们UI层属于客户端,客户端想要调用视频播放,需要用IPC方式通过bind服务的方式调用视频播放服务。(PS:如果大家对IPC不太熟悉可以参考我的其他文章 Android跨进程通信技术的使用及原理 )客户端可以通过调用bindService()绑定到服务。调用时,必须提供ServiceConnection的实现,后者会监控与服务的连接及销毁。
借助bindService的机制,我们可以在主进程创建时创建一个守护进程,并监听守护进程的连接及销毁,再守护进程bindService中绑定主进程,这样即使进程因为锁屏、内存等问题杀掉后,也会被守护进程拉起,这就是Android中双进程守护的概念。当然早在PC时期,网吧的计时系统就使用了双进程守护机制,防止被恶意杀掉。
实现方式就不写了,网络上一搜一堆,这里给出一篇文章
Android 双进程守护
写的中规中矩,如果不清楚如何实现可以看一下。
谷歌官方8.0变更
当版本8.0时,如果需要在后台启动服务需要调用startForegroundService。并且在serivce中onCreate方法必须在5秒内调用startForeground ,向通知栏发一个通知告知用户你的App正在后台运行,否则就会抛出异常
8.0通知适配
保活分两种:拉活、保活
拉活和保活是相辅相成的。在6.0版本以后的机型上,系统杀应用是按照进程组杀的,会直接导致双进程守护失效。那么因此就不使用双进程了么?
1.低版本双进程守护是依然亲测好使。
2.双进程守护可以和后面讲到的 账号同步、外部PUSH、JobScheduler
相结合,可以规避开系统杀进程组的问题。使双进程守护功能可以兼容高版本。
讲的有些笼统,我寻思的发Dome、写例子,但这样解决不了根本问题,只有懂得了思路,了解了什么是双进程守护,才能在开发中随机应变。只能说Android水太深,大家需要细心细心再细心。
Q5: Android保活方案
系统出于性能和体验上的考虑,APP退到后台后并不会真正的kill、掉进程,而是将其缓存起来。
打开的应用越多,缓存的应用也就越多,在系统进程不足的情况下,系统根据自己的一套进程回收机制,来判断kill掉哪些进程,以腾出进程给需要的app,这套进程回收机制叫做low memory killer。
内存阀值,每个手机都不一样,当可用内存小于该值得时候,Android就会杀死对应优先级得进程。
进程的优先级通过oom_adj来判断,oom_adj取值如下:
0-3是比较安全的oom_adj一般不会被系统杀死的,所以我们只要保证自己的app oom_adj在0-3之间就可以了。
可以通过adb命令:cat /proc /4181/oom_adj来查看自己app的oom_adj的值
4181是进程号
原理:手机关闭屏幕的时候,偷偷创建一个activity,让应用成为前台进程,打开屏幕时关闭activity,这样用户就不会发现什么异常,我们知道前台应用的oom_adj为0是不会被杀死的,这样就达到看保活的目的。
缺点:activity不够干净,只有在息屏的时候才生效,存在局限性比较大,而且谷歌原生的系统息屏的时候不会清理进程,但是现在很多厂商会在息屏的时候清理内存,所以本方案的可行性不高,可以作为了解。
保活原理:启动一个前台服务,从而拉高整个应用的优先级。
因为一旦通知被用户干掉那么该保活方案就不好用了,所以通知图标存在与否是该方案是否可行的关键。
但是该方案是谷歌官方承认的保活方案,所以可行性还是很高的。
需要适配
API18通知图标不会显示
API=18API26可以启动双服务,绑定同样的D,然后stop
这个方法的原理是8.0系统之前会根据服务的id来判断通知,那么第二个id设置跟第一个相同,然后自杀,系统就会误认为此通知已死就不会通知了,那么通知栏上面就不会显示
API=26后暂时没有方式能够隐藏
8.0之后不可以创建同样的id的通知,所以此隐藏通知的方法就不好用了,当然了,通知显示与否不是该方案成功的评判标准,所以说还是可以用的。
在发生特定系统事件时,系统会发出广播,通过在 Androidmanifest中静
态注册对应的广播监听器,即可在发生响应事件时拉活
但是从 android7.0开始,对广播进行了限制,而且在8.0更加严格该方法就不适用了。
有多个app在用户设备上安装,只要开启其中一个就可以将其他的app也拉
活。比如手机里装了手Q、QQ空间、兴趣部落等等,那么打开任意一个app后,其
他的app也都会被唤醒
系统每隔一段时间会进行账户同步,当系统去账户同步的时候(不一定多长时间,跟系统有关),我们就去拉活app,这个方案是非常稳定的,当然了国内的系统都是定制的,所以还是需要一定的适配的。
优点:系统唤醒,比较稳定
缺点:时间不能把控
JobScheduler允许在特定状态与特定时间间隔周期执行任务。可以利
用它的这个特点完成保活的功能,效果即开启一个定时器,与普通定时器不
同的是其调度由系统完成。
同样在某些ROM可能并不能达到需要的效果







