文章目录

  • 一、 双进程守护保活 + JobScheduler 原理
  • 二、 双进程守护保活 + JobScheduler 源码
    • 1、JobService 代码
    • 2、判定服务运行工具类
    • 3、清单文件
    • 4、MainActivity 代码
    • 5、运行效果
  • 三、 源码资源

一、 双进程守护保活 + JobScheduler 原理


【Android 进程保活】应用进程拉活 ( JobScheduler 拉活 | JobScheduler 使用流程 | JobService 服务 | 不同版本兼容 | 源码资源 ) 博客中介绍了 JobScheduler 的用法 ;

【Android 进程保活】应用进程拉活 ( 双进程守护保活 ) 博客中介绍了双进程守护保活用法 ;

使用 " 双进程守护保活 + JobScheduler " 机制 , 成功率最高 ;

" 双进程守护保活 + JobScheduler " 整合方法 :

在 JobService 的 onStartJob 方法中 , 判定 " 双进程守护保活 " 中的双进程是否挂了 , 如果这两个进程挂了 , 就重新将挂掉的进程重启 ;

判定 Service 进程是否运行 :

    public static boolean isServiceRunning(Context context, String serviceName){if(TextUtils.isEmpty(serviceName)) return false;ActivityManager activityManager =(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);// 最多获取 200 个正在运行的 ServiceList<ActivityManager.RunningServiceInfo> infos =activityManager.getRunningServices(200);// 遍历当前运行的 Service 信息, 如果找到相同名称的服务 , 说明某进程正在运行for (ActivityManager.RunningServiceInfo info: infos){if (TextUtils.equals(info.service.getClassName(), serviceName)){return true;}}return false;}

二、 双进程守护保活 + JobScheduler 源码


大部分代码与 【Android 进程保活】应用进程拉活 ( 双进程守护保活 ) 博客中重复 , 这里只贴出 JobScheduler 相关源码 ;

1、JobService 代码

package kim.hsl.two_progress_alive;import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;import androidx.annotation.RequiresApi;@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class KeepAliveJobService extends JobService {@Overridepublic boolean onStartJob(JobParameters params) {Log.i("KeepAliveJobService", "JobService onStartJob 开启");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){// 如果当前设备大于 7.0 , 延迟 5 秒 , 再次执行一次startJob(this);}// 判定本地前台进程是否正在运行boolean isLocalServiceRunning =ServiceUtils.isServiceRunning(this, LocalForegroundService.class.getName());if (!isLocalServiceRunning){startService(new Intent(this, LocalForegroundService.class));}// 判定远程前台进程是否正在运行boolean isRemoteServiceRunning =ServiceUtils.isServiceRunning(this, RemoteForegroundService.class.getName());if (!isRemoteServiceRunning){startService(new Intent(this, RemoteForegroundService.class));}return false;}@Overridepublic boolean onStopJob(JobParameters params) {Log.i("KeepAliveJobService", "JobService onStopJob 关闭");return false;}public static void startJob(Context context){// 创建 JobSchedulerJobScheduler jobScheduler =(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);// 第一个参数指定任务 ID// 第二个参数指定任务在哪个组件中执行// setPersisted 方法需要 android.permission.RECEIVE_BOOT_COMPLETED 权限// setPersisted 方法作用是设备重启后 , 依然执行 JobScheduler 定时任务JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(10,new ComponentName(context.getPackageName(), KeepAliveJobService.class.getName())).setPersisted(true);// 7.0 以下的版本, 可以每隔 5000 毫秒执行一次任务if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N){jobInfoBuilder.setPeriodic(5_000);}else{// 7.0 以上的版本 , 设置延迟 5 秒执行// 该时间不能小于 JobInfo.getMinLatencyMillis 方法获取的最小值jobInfoBuilder.setMinimumLatency(5_000);}// 开启定时任务jobScheduler.schedule(jobInfoBuilder.build());}
}

2、判定服务运行工具类

package kim.hsl.two_progress_alive;import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.text.TextUtils;import org.w3c.dom.Text;import java.util.List;public class ServiceUtils {/*** 判定 Service 是否在运行* @param context* @return*/public static boolean isServiceRunning(Context context, String serviceName){if(TextUtils.isEmpty(serviceName)) return false;ActivityManager activityManager =(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);// 最多获取 200 个正在运行的 ServiceList<ActivityManager.RunningServiceInfo> infos =activityManager.getRunningServices(200);// 遍历当前运行的 Service 信息, 如果找到相同名称的服务 , 说明某进程正在运行for (ActivityManager.RunningServiceInfo info: infos){if (TextUtils.equals(info.service.getClassName(), serviceName)){return true;}}return false;}
}

3、清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="kim.hsl.two_progress_alive"><uses-permission android:name="android.permission.FOREGROUND_SERVICE" /><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.Two_Progress_Alive"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><!-- 本地提权前台服务 Service --><serviceandroid:name=".LocalForegroundService"android:enabled="true"android:exported="true"></service><!-- 本地服务 , API 18 ~ 25 以上的设备, 关闭通知到专用服务 --><serviceandroid:name=".LocalForegroundService$CancelNotificationService"android:enabled="true"android:exported="true"></service><!-- 远程提权前台服务 Service --><serviceandroid:name=".RemoteForegroundService"android:enabled="true"android:exported="true"android:process=":remote"></service><!-- 远程服务 , API 18 ~ 25 以上的设备, 关闭通知到专用服务 --><serviceandroid:name=".RemoteForegroundService$CancelNotificationService"android:enabled="true"android:exported="true"android:process=":remote"></service><!-- JobScheduler 拉活 --><serviceandroid:name=".KeepAliveJobService"android:enabled="true"android:exported="true"android:permission="android.permission.BIND_JOB_SERVICE"></service></application></manifest>

4、MainActivity 代码

package kim.hsl.two_progress_alive;import android.content.Intent;
import android.os.Build;
import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 通过前台 Service 提升应用权限// 启动普通 Service , 但是在该 Service 的 onCreate 方法中执行了 startForeground// 变成了前台 Service 服务startService(new Intent(this, LocalForegroundService.class));startService(new Intent(this, RemoteForegroundService.class));// JobScheduler 拉活if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {KeepAliveJobService.startJob(this);}}
}

5、运行效果

运行后 , 两个进程成功运行 ;

即使将启动双进程的代码注释掉 , 也可以成功拉起双进程 ;

三、 源码资源


源码资源 :

  • GitHub 地址 : https://github.com/han1202012/Two_Progress_Alive
  • CSDN 源码快照 : https://download.csdn.net/download/han1202012/16623594

【Android 进程保活】应用进程拉活 ( 双进程守护 + JobScheduler 保活 | 成功率最高 | 推荐使用 )相关推荐

  1. 【Android 进程保活】应用进程拉活 ( 双进程守护保活 )

    文章目录 一. 双进程守护保活原理 二. 双进程守护保活完整源码 1.AIDL 接口 2.本地前台服务 Service 3.远程前台服务 Service 4.清单配置 5.启动两个服务 5.执行效果 ...

  2. 【Android 进程保活】应用进程拉活 ( 账户同步拉活 | 账号添加 | 源码资源 )

    文章目录 一. 账号添加 二. 代码示例 1. 账号添加工具类 2. 权限注册 3. 在 Activity 中调用上述工具类 4. 运行效果 三. 源码资源 一. 账号添加 在上一篇博客 [Andro ...

  3. Android进程保活、拉活方案

    引言 最近产品提出了一个非常BT的需求,说我们所做的APP要做到像微信和QQ那种即时用户清理了进程还是能收到消息的效果,当时心中就卧槽了一顿,虽然心里一万只曹尼玛翻滚着,但是功能还是要做啊,因为生活还 ...

  4. Android7.0 8.0进程保活与拉活的实现方式

    进程保活 前言 APP进程被系统杀死 Low Memory Killer 进程优先级 进程保活 1px Activity 前台Service 进程拉活 粘性Service JobScheduler 双 ...

  5. 解密Android7.0 8.0进程保活与拉活的实现方式 如何才能让APP常驻内存 躲避系统的追杀

    进程保活 前言 APP进程被系统杀死 Low Memory Killer 进程优先级 进程保活 1px Activity 前台Service 进程拉活 粘性Service JobScheduler 双 ...

  6. 【Android 进程保活】应用进程拉活 ( 系统 Service 机制拉活 | Service 组件 onStartCommand 方法分析 | 源码资源 )

    文章目录 一. Service 组件 onStartCommand 方法分析 1. onStartCommand 函数返回值分析 2. onStartCommand 函数 START_STICKY_C ...

  7. 【Android】锁屏后应用保活、拉活、双进程守护

    最近在使用高德地图实时获取定位时遇到了个问题,锁屏后一段时间(5~10分钟左右)后程序会被系统杀死,为了保活,特研究了下进程保活机制. 0.基本操作和概念 针对root过的手机,可以通过下列命令查看内 ...

  8. 【Android 进程保活】应用进程拉活 ( JobScheduler 拉活 | JobScheduler 使用流程 | JobService 服务 | 不同版本兼容 | 源码资源 )

    文章目录 一. JobScheduler 用法简介 二. JobScheduler 拉活完整代码 1. JobService 2.清单文件 3.启动 JobScheduler 任务 4.运行效果 三. ...

  9. 进程保活与拉活——APP黑科技,永生不死!

    我相信很多开发朋友都像我一样遇到过这样的需求,尤其是开发过IM对实时性要求比较高的朋友.一定遇到过老板或者产品经理发出来的要求我们做到像微信,钉钉等等这些大厂应用一样保持应用一直保活,能够实时接收到推 ...

最新文章

  1. kafka模拟生产-消费者以及自定义分区
  2. RBSP、SODB、EBSP三者的区别和联系 SPS: sequence parameter sets
  3. 中科大计算机考研科学岛,科学岛研究生_请问谁知道研究生去合肥科学岛与在学校的利与弊啊着急!!!!_淘题吧...
  4. php xml 接口调用,php的SimpleXML方法读写XML接口文件实例解析
  5. jmeter压力性能测试-多台机器并发请求
  6. laravel框架连接Oracle,laravel5.8(十四)连接oracle数据库
  7. git复制迁移--SmartGit
  8. 6大维度重磅升级,容器云平台BeyondContainer发布1.8版本
  9. QtAndroid具体解释(6):集成信鸽推送
  10. #C语言#6.1 数据类型 笔记
  11. 生日祝福卡片 html,暖心的卡片生日祝福语
  12. 中医针灸学综合练习题库【11】
  13. Spring+SpringMVC+Mybatis(开发必备技能)04、mybatis自动生成mapper_dao_model(包含工具与视频讲解) 纯绿色版本、配套使用视频,100%运行成功
  14. webservice报错Message part refundRequest was not recognized. (Does it exist in service WSDL?)
  15. 【涂鸦物联网足迹】涂鸦云平台接口列表—万能红外遥控器
  16. HTTP 必备干货学习,一篇HTTP入门 不收藏都可惜!
  17. 智能垃圾桶语音芯片应用设计方案介绍,WT588F02B-8S
  18. 阿里云短信功能网址链接
  19. java 抛出异常后,还会执行后面代码吗?
  20. c语言程序设计新编教程答案钱雪忠,新编C语言程序设计教程

热门文章

  1. 如何設定 VS2008 讓 HTML 在格式化排版時不要破壞版面
  2. 后盾网lavarel视频项目---lavarel用户认证实例
  3. 看jquery3.3.1学js类型判断的技巧
  4. POJ 3660 Cow Contest [Floyd]
  5. 你说你精通CSS,真的吗?
  6. android zip解压缩
  7. 接口到底是什么(一语道破)
  8. js中获得当前时间是年份和月份
  9. web移动端全屏滚动页面的适配问题
  10. QT5 QT4--LNK2019 无法解析的外部符号