Я хочу реализовать долгосрочную фоновую службу, например, 1 час, для отслеживания позы пользователя с помощью фронтальной камеры, когда пользователь играет на телефоне.Тем не менее, служба прерывается системой неожиданно всего за несколько минут.
Код тестирования здесь
TestJobSchedulerActivity.java
public class TestJobSchedulerActivity extends AppCompatActivity {
private final String TAG = this.getClass().getSimpleName();
private ComponentName mServiceComponent;
private int mJobId = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_job_scheduler);
mServiceComponent = new ComponentName(this, EyeCareJobService.class);
}
// @RequiresApi(api = Build.VERSION_CODES.O)
public void startJobService(View v){
JobInfo.Builder builder = new JobInfo.Builder(mJobId++, mServiceComponent);
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
Log.d(TAG, "Scheduling job");
JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
tm.schedule(builder.build());
}
public void stopJobService(View v){
JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
tm.cancelAll();
}
}
EyeCareService.java:
public class EyeCareJobService extends JobService {
private final String TAG = this.getClass().getSimpleName();
private VisionAI visionAI;
private boolean isRunning = true;
private HandlerThread mBackgroundThread;
private Handler mBackgroundHandler;
private long startTimestamp;
private Runnable mInitializeOnBackground = new Runnable() {
@Override
public void run() {
// image processing to the camera preview frame data
visionAI.start();
}
};
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service created, thread id = " + Thread.currentThread().getId());
visionAI = VisionAI.getInstance(this.getApplicationContext());
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroyed");
}
@Override
public boolean onStartJob(JobParameters params) {
Log.d(TAG, "onStartJob(), thread id = " + Thread.currentThread().getId());
startTimestamp = System.currentTimeMillis();
mBackgroundThread = new HandlerThread("BackgroundThread");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
mBackgroundHandler.post(mInitializeOnBackground);
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
Log.d(TAG, "onStopJob()");
try{
throw new Exception();
}catch (Exception ex){
ex.printStackTrace();
}
long ts = System.currentTimeMillis();
Log.d(TAG, "jobservice runing time = " + (ts - startTimestamp));
setRunning(false);
visionAI.stop();
return false;
}
public synchronized boolean isRunning() {
return isRunning;
}
public synchronized void setRunning(boolean running) {
isRunning = running;
}
}
Отслеживание Logcat:
09-11 16:35:41.913 13238-13238/cn.com.hotcent.eyecare D/TestJobSchedulerActivity: Scheduling job
09-11 16:35:42.002 13238-13238/cn.com.hotcent.eyecare I/EyeCareJobService: Service created, thread id = 1
09-11 16:35:42.011 13238-13238/cn.com.hotcent.eyecare D/EyeCareJobService: onStartJob(), thread id = 1
...
...
...
09-11 16:38:50.596 13238-13238/cn.com.hotcent.eyecare D/EyeCareJobService: onStopJob()
09-11 16:38:50.596 13238-13238/cn.com.hotcent.eyecare W/System.err: java.lang.Exception
09-11 16:38:50.647 13238-13238/cn.com.hotcent.eyecare W/System.err: at cn.com.hotcent.eyecare.service.EyeCareJobService.onStopJob(EyeCareJobService.java:76)
at android.app.job.JobService$JobHandler.handleMessage(JobService.java:135)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:5529)
at java.lang.reflect.Method.invoke(Native Method)
09-11 16:38:50.648 13238-13238/cn.com.hotcent.eyecare W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
09-11 16:38:50.648 13238-13238/cn.com.hotcent.eyecare D/EyeCareJobService: jobservice runing time = 177770
09-11 16:38:50.689 13238-13238/cn.com.hotcent.eyecare D/VisionAI: stop camera
Когда служба запускается, я переключаюсь на другое приложение, такое как воспроизведение видео.Но только через 3 минуты сервисное обслуживание завершается системой.Похоже, кто-то неизвестный отправил сообщение о прекращении в сервисную службу.Что здесь происходит?Как я могу поддерживать работу службы заданий?
Спасибо.
Приложение: После того, как я копаюсь в трассировке logcat, служба отключается из-за сохранения питания и не может перезапуститься в будущем.
09-13 17:03:34.755 2282-7723/? D/PowerKeeper.KillControl: calling Whetstone killApplication, pkg = cn.com.hotcent.eyecare
09-13 17:03:34.763 5988-8968/cn.com.hotcent.eyecare D/VisionAI: onPreviewFrame(): data size = 1382400, width = 1280, height = 720
09-13 17:03:34.768 5988-8968/cn.com.hotcent.eyecare D/VisionAI: Face size=0
09-13 17:03:34.772 1282-2113/? I/ActivityManager: Force stopping cn.com.hotcent.eyecare appid=10244 user=0: from pid 2030
Killing 5988:cn.com.hotcent.eyecare/u0a244 (adj 1): stop cn.com.hotcent.eyecare: from pid 2030
09-13 17:03:34.774 1282-2113/? I/AutoStartManagerService: MIUILOG- Reject RestartService packageName :cn.com.hotcent.eyecare uid : 10244
MIUILOG- Reject RestartService packageName :cn.com.hotcent.eyecare uid : 10244
09-13 17:03:34.777 1282-2113/? I/ActivityManager: Force finishing activity ActivityRecord{7564d u0 cn.com.hotcent.eyecare/.activity.MainActivity t22161}
09-13 17:03:34.778 1282-2113/? I/ActivityManager: Force stopping service ServiceRecord{762b751 u0 cn.com.hotcent.eyecare/.service.EyeCareJobService}
09-13 17:03:34.781 2030-16569/? W/WtProcessController: killApplication F: cn.com.hotcent.eyecare, mask=0, uid=10244, reason=com.miui.powerkeeper
09-13 17:04:04.801 1282-1282/? I/AutoStartManagerService: MIUILOG- Reject service :Intent { cmp=cn.com.hotcent.eyecare/.service.EyeCareJobService } userId : 0 uid : 10244
Как предотвратить отключение службы Powerkeeper или включить службу автоматического запуска?