Android服务保活-JobScheduler拉活

  • 内容
  • 评论
  • 相关
方案设计

Android5.0 以后系统对 Native 进程等加强了管理,Native 拉活方式失效。系统在 Android5.0 以上版本提供了 JobScheduler 接口,系统会定时调用该进程以使应用进行一些逻辑操作。

方案适用范围

该方案主要适用于 Android5.0 以上版本手机。

该方案在 Android5.0 以上版本中不受 forcestop 影响,被强制停止的应用依然可以被拉活,在 Android5.0 以上版本拉活效果非常好。

仅在小米手机可能会出现有时无法拉活的问题。

方案实现

JobSchedulerService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.aoaoyi.service;
 
import android.annotation.TargetApi;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Intent;
import android.os.Build;
 
/**
 * Created by xy on 2016/12/2.
 */
 
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class JobSchedulerService extends JobService{
 
    @Override
    public boolean onStartJob(JobParameters params) {
        startMainService();
        jobFinished(params, false);
        return true;
    }
 
    @Override
    public boolean onStopJob(JobParameters params) {
        startMainService();
        return false;
    }
 
    @Override
    public void onTaskRemoved(Intent rootIntent) {
        startMainService();
    }
 
    public void startMainService(){
        startService(MainService.getIntentAlarm(this));
    }
}

在AndroidManifest.xml中注册

1
2
3
4
5
6
 <service
 android:name="com.aoaoyi.service.JobSchedulerService"
 android:permission="android.permission.BIND_JOB_SERVICE"
 android:enabled="true"
 android:exported="true"
 android:process=":push"/>

在AndroidManifest.xml中加入权限

1
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

 

MainService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.aoaoyi.service;
 
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
 
public class MainService extends Service {
 
    /**
     * 每10分钟检查一次链接状态,确保service不被杀掉
     */
    private static final int KEEP_ALIVE_INTERVAL = BuildConfig.DEBUG ? 1 * 60 * 1000 : 10 * 60 * 1000;
 
    /**
     * ACTION Start
     */
    private static final String ACTION_START = "MainService.Action.Start";
    /**
     * ACTION Alarm
     */
    private static final String ACTION_ALARM = "MainService.Action.Alarm";
    /**
     * ACTION end start
     */
    private static final String ACTION_END_START = "MainService.Action.EndStart";
 
    private boolean mIsAddAliveAlarm = false;
 
    public MainService() {
 
    }
 
    @Override
    public IBinder onBind(Intent intent) {
 
        return null;
    }
 
    @Override
    public void onCreate() {
        if (!mIsAddAliveAlarm){
            addAliveAlarm();
            mIsAddAliveAlarm = true;
        }
        super.onCreate();
    }
 
    @Override
    public int onStartCommand(Intent pIntent, int pFlags, int pStartId) {
        if (null != pIntent){
            switch (pIntent.getAction()){
                case ACTION_START:
 
                    break;
                case ACTION_ALARM:
 
                    break;
                case ACTION_END_START:
 
                    break;
            }
        }
        if (!mIsAddAliveAlarm){
            addAliveAlarm();
            mIsAddAliveAlarm = true;
        }
        return START_STICKY;
    }
 
    @Override
    public void onTaskRemoved(Intent pIntent) {
        onEnd();
    }
 
    @Override
    public void onDestroy() {
        onEnd();
        super.onDestroy();
    }
 
    private void onEnd() {
        startService(getIntentEndStart(getApplicationContext()));
    }
 
 
    /**
     * 添加重复唤醒闹钟,用于不停唤起服务
     */
    private void addAliveAlarm() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            JobInfo.Builder _Builder = new JobInfo.Builder(0, new ComponentName(getApplication(), JobSchedulerService.class));
            _Builder.setPeriodic(KEEP_ALIVE_INTERVAL);
            _Builder.setPersisted(true);
            JobScheduler _JobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
            _JobScheduler.schedule(_Builder.build());
        }else {
            PendingIntent _PendingIntent = PendingIntent.getService(this, 0, getIntentAlarm(this), PendingIntent.FLAG_UPDATE_CURRENT);
            AlarmManager _AlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
            _AlarmManager.cancel(_PendingIntent);
            _AlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + KEEP_ALIVE_INTERVAL, KEEP_ALIVE_INTERVAL, _PendingIntent);
        }
    }
 
    /**
     * Start
     *
     * @param pContext
     */
    public static Intent getIntentStart(Context pContext) {
        return getActionIntent(pContext, ACTION_START);
    }
 
    /**
     * Alarm
     *
     * @param pContext
     */
    public static Intent getIntentAlarm(Context pContext) {
        return getActionIntent(pContext, ACTION_ALARM);
    }
 
    /**
     * EndStart
     *
     * @param pContext
     */
    public static Intent getIntentEndStart(Context pContext) {
        return getActionIntent(pContext, ACTION_END_START);
    }
 
    /**
     * Service Intent
     *
     * @param pContext
     * @param pAction
     * @return
     */
    private static Intent getActionIntent(Context pContext, String pAction) {
        Intent _Intent = new Intent(pContext, MainService.class);
        _Intent.setAction(pAction);
        return _Intent;
    }
 
}

最后一步,在主Activity启动一次MainService

 

1
startService(MainService.getIntentStart(this));

 

效果试试哦^_^

 

评论

3条评论
  1. Gravatar 头像

    Jady

    Greetings from Ohio! I’m bored at work so I decided to check out your website on my iphone during lunch break. I enjoy the knowledge you present here and can#;8217&t wait to take a look when I get home. I’m amazed at how fast your blog loaded on my cell phone .. I’m not even using WIFI, just 3G .. Anyhow, great blog!

  2. Gravatar 头像

    Kailee

    Oi Vany tudo bem?Menina amei as bijus!! Parabéns por ter sido sorteada!!É muito bom ganhar!!Ah!! Parabéns pelo niver de casamento!!Não deixem de coBjeorar!!mmieos

发表评论