第一 :启动系统任务
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sports);
// 2. 启动系统任务
mJobManager = JobSchedulerManager.getJobSchedulerInstance(this);
mJobManager.startJobScheduler();
}
系统任务:
import android.annotation.TargetApi;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.os.Build;
import com.jiangdg.keepappalive.service.AliveJobService;
/**JobScheduler管理类,单例模式
* 执行系统任务
*
* Created by jianddongguo on 2017/7/10.
* http://blog.csdn.net/andrexpert
*/
public class JobSchedulerManager {
private static final int JOB_ID = 1;
private static JobSchedulerManager mJobManager;
private JobScheduler mJobScheduler;
private static Context mContext;
private JobSchedulerManager(Context ctxt){
this.mContext = ctxt;
mJobScheduler = (JobScheduler)ctxt.getSystemService(Context.JOB_SCHEDULER_SERVICE);
}
public final static JobSchedulerManager getJobSchedulerInstance(Context ctxt){
if(mJobManager == null){
mJobManager = new JobSchedulerManager(ctxt);
}
return mJobManager;
}
@TargetApi(21)
public void startJobScheduler(){
// 如果JobService已经启动或API<21,返回
if(AliveJobService.isJobServiceAlive() || isBelowLOLLIPOP()){
return;
}
// 构建JobInfo对象,传递给JobSchedulerService
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID,new ComponentName(mContext, AliveJobService.class));
// 设置每2秒执行一下任务
builder.setPeriodic(3000);
// 设置设备重启时,执行该任务
builder.setPersisted(true);
// 当插入充电器,执行该任务
builder.setRequiresCharging(true);
JobInfo info = builder.build();
//开始定时执行该系统任务
mJobScheduler.schedule(info);
}
@TargetApi(21)
public void stopJobScheduler(){
if(isBelowLOLLIPOP())
return;
mJobScheduler.cancelAll();
}
private boolean isBelowLOLLIPOP(){
// API< 21
return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP;
}
}
保活Service :Contants.PACKAGE_NAME 为保活APP的包名
import android.annotation.TargetApi;
import android.app.Service;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
import com.jiangdg.keepappalive.SportsActivity;
import com.jiangdg.keepappalive.utils.Contants;
import com.jiangdg.keepappalive.utils.SystemUtils;
/**JobService,支持5.0以上forcestop依然有效
*
* Created by jianddongguo on 2017/7/10.
*/
@TargetApi(21)
public class AliveJobService extends JobService {
private final static String TAG = "KeepAliveService";
// 告知编译器,这个变量不能被优化
private volatile static Service mKeepAliveService = null;
public static boolean isJobServiceAlive(){
return mKeepAliveService != null;
}
private static final int MESSAGE_ID_TASK = 0x01;
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// 具体任务逻辑
if(SystemUtils.isAPPALive(getApplicationContext(), Contants.PACKAGE_NAME)){
Toast.makeText(getApplicationContext(), "APP活着的", Toast.LENGTH_SHORT)
.show();
}else{
Intent intent = new Intent(getApplicationContext(), SportsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Toast.makeText(getApplicationContext(), "APP被杀死,重启...", Toast.LENGTH_SHORT)
.show();
}
// 通知系统任务执行结束
jobFinished( (JobParameters) msg.obj, false );
return true;
}
});
@Override
public boolean onStartJob(JobParameters params) {
if(Contants.DEBUG)
Log.d(TAG,"KeepAliveService----->JobService服务被启动...");
mKeepAliveService = this;
// 返回false,系统假设这个方法返回时任务已经执行完毕;
// 返回true,系统假定这个任务正要被执行
Message msg = Message.obtain(mHandler, MESSAGE_ID_TASK, params);
mHandler.sendMessage(msg);
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
mHandler.removeMessages(MESSAGE_ID_TASK);
if(Contants.DEBUG)
Log.d(TAG,"KeepAliveService----->JobService服务被关闭");
return false;
}
}
工具类
**工具类
*
* Created by jianddongguo on 2017/7/10.
* http://blog.csdn.net/andrexpert
*/
public class SystemUtils {
/**
* 判断本应用是否存活
* 如果需要判断本应用是否在后台还是前台用getRunningTask
* */
public static boolean isAPPALive(Context mContext,String packageName){
boolean isAPPRunning = false;
// 获取activity管理对象
ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
// 获取所有正在运行的app
List<ActivityManager.RunningAppProcessInfo> appProcessInfoList = activityManager.getRunningAppProcesses();
// 遍历,进程名即包名
for(ActivityManager.RunningAppProcessInfo appInfo : appProcessInfoList){
if(packageName.equals(appInfo.processName)){
isAPPRunning = true;
break;
}
}
return isAPPRunning;
}
}
配置文件中:
<service android:name=".service.AliveJobService" android:permission="android.permission.BIND_JOB_SERVICE"/>
原理:
APP复活方案探讨和实践
JobScheduler是谷歌在Android 5.0引入的一个能够执行某项任务的API,它允许APP在将来达到一定条件时执行指定的任务。通常情况下,即使APP被强制停止,预定的任务仍然会被执行。
JobScheduler工作原理:
首先在一个实现了JobService的子类的onStartJob方法中执行这项任务,使用JobInfo的Builder方法来设定条件并和实现了JobService的子类的组件名绑定,然后调用系统服务JobScheduler的schedule方法。这样,即便在执行任务之前应用程序进程被杀,也不会导致任务不会执行,因为系统服务JobScheduler会使用bindServiceAsUser的方法把实现了JobService的子类服务启动起来,并执行它的onStartJob方法。