文章目录

  • 一、 JobScheduler 用法简介
  • 二、 JobScheduler 拉活完整代码
    • 1、 JobService
    • 2、清单文件
    • 3、启动 JobScheduler 任务
    • 4、运行效果
  • 三、 源码资源

一、 JobScheduler 用法简介


JobScheduler 机制可以规定在特定状态 , 特定时间 , 执行周期性任务 ;

JobScheduler 是系统服务 , 由系统负责调度第三方应用注册的 JobScheduler , 定时完成指定任务 ;

部分设备 , 版本 , 无法达到拉活效果 ;

这种拉活方式 , 需要在 API Level 212121 以上才可以使用 ;

在应用中 , 创建一个 JobService 服务 , JobService 需要 API Level 212121 ;

该服务注册时必须声明 android.permission.BIND_JOB_SERVICE 权限 ;

        <!-- JobScheduler 拉活 --><serviceandroid:name=".jobscheduler.KeepAliveJobService"android:enabled="true"android:exported="true"android:permission="android.permission.BIND_JOB_SERVICE"></service>

JobScheduler 用法 :

① 获取 JobScheduler 对象 : 通过 Binder 机制获取该 JobScheduler 系统服务 ;

// 创建 JobScheduler
JobScheduler jobScheduler =(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);

② 指定 JobScheduler 任务信息 JobInfo : 绑定任务 ID , 指定任务的运行组件 , 也就是之前创建并注册的 JobService , 最后要设置该任务在重启后也要执行 ;

// 第一个参数指定任务 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.07.07.0 以下的系统可以设置间隔 , 7.07.07.0 以上设置不了 ; 7.07.07.0 以上的版本需要设置延迟执行 , 否则无法启动 ;

// 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());

⑤ 7.07.07.0 以上的特殊处理 : 由于在 7.07.07.0 以上的系统中设置了延迟执行 , 需要在 JobService 的 onStartJob 方法中 , 再次开启一次 JobScheduler 任务执行 , 也就是重复上述 ① ~ ④ 执行 , 这样就实现了周期性执行的目的 ;

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);}return false;}
}

二、 JobScheduler 拉活完整代码


1、 JobService

package kim.hsl.keep_progress_alive.jobscheduler;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.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);}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、清单文件

核心配置 :

        <!-- JobScheduler 拉活 --><serviceandroid:name=".jobscheduler.KeepAliveJobService"android:enabled="true"android:exported="true"android:permission="android.permission.BIND_JOB_SERVICE"></service>

完整配置 :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="kim.hsl.keep_progress_alive"><uses-permission android:name="android.permission.FOREGROUND_SERVICE" /><uses-permissionandroid:name="android.permission.GET_ACCOUNTS"android:maxSdkVersion="22" /><uses-permissionandroid:name="android.permission.AUTHENTICATE_ACCOUNTS"android:maxSdkVersion="22" /><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><uses-permissionandroid:name="android.permission.WRITE_SYNC_SETTINGS"/><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.Keep_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><!--设置最近任务列表中不显示该 Activity 组件 ( 不要被用户察觉 )android:excludeFromRecents="true"设置 Activity 亲和性让该界面在一个独立的任务栈中 , 不要与本应用的其它任务栈放在一起避免解除锁屏后 , 关闭 1 像素界面 , 将整个任务栈都唤醒android:taskAffinity="kim.hsl.keep_progress_alive.alive"--><activityandroid:name=".one_pixel_activity.OnePixelActivity"android:excludeFromRecents="true"android:taskAffinity="kim.hsl.keep_progress_alive.onepixel"android:theme="@style/OnePixelActivityTheme" /><!-- 用于提权的前台进程 --><serviceandroid:name=".foreground_service.ForegroundService"android:enabled="true"android:exported="true" /><!-- 用于提权的前台进程, 关闭通知操作 --><serviceandroid:name=".foreground_service.CancelNotificationService"android:enabled="true"android:exported="true" /><!-- 系统 Service 机制拉活 --><serviceandroid:name=".stick_service.StickService"android:enabled="true"android:exported="true" /><!-- 用于账户同步拉活 --><serviceandroid:name=".account_service.AuthenticationService"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.accounts.AccountAuthenticator" /></intent-filter><meta-dataandroid:name="android.accounts.AccountAuthenticator"android:resource="@xml/account_authenticator" /></service><!-- 账户同步服务 --><serviceandroid:name=".account_service.AccountSyncService"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.content.SyncAdapter" /></intent-filter><meta-dataandroid:name="android.content.SyncAdapter"android:resource="@xml/sync_adapter" /></service><!-- 账户同步 ContentProvider --><providerandroid:authorities="kim.hsl.keep_progress_alive.provider"android:name=".account_service.AccountSyncContentProvider" /><!-- JobScheduler 拉活 --><serviceandroid:name=".jobscheduler.KeepAliveJobService"android:enabled="true"android:exported="true"android:permission="android.permission.BIND_JOB_SERVICE"></service></application></manifest>

3、启动 JobScheduler 任务

package kim.hsl.keep_progress_alive;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.os.Build;
import android.os.Bundle;import kim.hsl.keep_progress_alive.account_service.AccountUtils;
import kim.hsl.keep_progress_alive.foreground_service.ForegroundService;
import kim.hsl.keep_progress_alive.jobscheduler.KeepAliveJobService;
import kim.hsl.keep_progress_alive.one_pixel_activity.KeepProgressAliveManager;
import kim.hsl.keep_progress_alive.stick_service.StickService;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 1.  1 像素 Activity 提升应用权限// 注册广播接收者 , 1 像素 Activity 启动的 广播接收者//KeepProgressAliveManager.getmInstance().registerReceiver(this);// 2. 通过前台 Service 提升应用权限// 启动普通 Service , 但是在该 Service 的 onCreate 方法中执行了 startForeground// 变成了前台 Service 服务//startService(new Intent(this, ForegroundService.class));// 3. 使用 Service 机制拉活//startService(new Intent(this, StickService.class));// 4. 账户同步拉活//AccountUtils.addAccount(this);// 开始同步//AccountUtils.autoSyncStart();// 5. JobScheduler 拉活if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {KeepAliveJobService.startJob(this);}}@Overrideprotected void onDestroy() {super.onDestroy();// 1. 取消注册广播接收者, 也可以不取消注册//KeepProgressAliveManager.getmInstance().registerReceiver(this);}
}

4、运行效果

每隔 5 秒调用一次 ;

三、 源码资源


源码资源 :

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

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

  1. Android进程保活(黑白手段让APP活下去)

    凡是做过几年Android开发的,都不能不面对进程保活这一问题.特别是这两年,面对谷歌,国内定制ROM,安全软件等多方围剿的情况下,app在后台保活的难度越来越大,可以说包括QQ.微信在内的所有app ...

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

    文章目录 一. 双进程守护保活 + JobScheduler 原理 二. 双进程守护保活 + JobScheduler 源码 1.JobService 代码 2.判定服务运行工具类 3.清单文件 4. ...

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

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

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

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

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

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

  6. 【Android 进程保活】提升进程优先级 ( 使用前台 Service 提高应用进程优先级 | 启动相同 id 的第二个前台 Service 关闭通知 )

    文章目录 一. 前台 Service 通知问题 二. 设置 startForeground id 参数为 0 三. 启动相同 id 的第二个前台 Service 关闭通知 1. 前台服务 1 2. 关 ...

  7. 【Android 进程保活】提升进程优先级 ( 使用前台 Service 提高应用进程优先级 | 效果展示 | 源码资源 )

    文章目录 一. 使用前台 Service 提高应用进程优先级 1. 前台 Service 代码 2. 前台 Service 代码 3. 启动服务 二.效果展示 三.源码资源 一. 使用前台 Servi ...

  8. Android 系统(146)----Android进程保活招数概览

    Android进程保活招数概览 Android中的进程保活应该分为两个方面: 提高进程的优先级,减少被系统杀死的可能性 在进程已经被杀死的情况下,通过一些手段来重新启动应用进程 本文针对这两方面来进程 ...

  9. Android进程保活的一般套路

    自己曾经也在这个问题上伤过脑经,前几日刚好有一个北京的哥们在QQ说在做IM类的项目,问我进程保活如何处理比较恰当,决定去总结一下,网上搜索一下进程常驻的方案好多好多,但是很多的方案都是不靠谱的或者不是 ...

最新文章

  1. 06年做的一个配置,从net130转过来的
  2. 前端学习(2183):tabber--基本架构的构建
  3. java netty post_API调用Netty长链接执行发送消息(在线数、用户列表)
  4. FreeSWITCH的NAT穿越
  5. vmware Horizon View 5.2初体验(三)——composer安装
  6. SQL语句优化常见方法
  7. qq透明图像问题#13
  8. 简明python教程最新pdf_《简明Python教程》PDF高清 初学者的极佳教材 限时免费领取...
  9. 【Python自动化Excel】pandas处理Excel数据的基本流程
  10. 从零搭建一个vue项目
  11. Godot特效:手绘贴图+粒子系统实现风格化火焰(一)绘制火焰贴图
  12. 几款永久免费内网穿透,好用且简单
  13. 不限距离4g/5g信号远程遥控小车
  14. 【C语言】求一个数有多少位
  15. js 对象的解构赋值
  16. .NET ASP.NET支付宝支付接口调用实现
  17. 【ZZ】 移位贴图 Displacement Mapping
  18. 【解决方案】国标视频平台EasyGBS如何搭建应急管理与安全生产平台
  19. ROS回顾学习(11): TF之static_transform_publisher
  20. 谷粒商城关键技术总结-复习必备

热门文章

  1. IE6 CSS的一个bug
  2. 菜鸟requireJS教程---2、基本知识
  3. xnawindowsph又见“X”Phone ePhone手机V90新鲜评测
  4. 从CMOS到触发器(一)
  5. JQuery面试题1
  6. Android实例-MotionSensor加速度(XE8+小米2)
  7. UVa 11107 (后缀数组 二分) Life Forms
  8. jQuery UI Autocomplete示例(一)
  9. [EffectiveC++]item41:了解隐式接口和编译期多态
  10. iView 实现可编辑表格