Android Priority Job Queue (Job Manager):线程任务的容错重启机制(二)

附录文章4简单介绍了如何启动一个后台线程任务,Android Priority Job Queue (Job Manager)有一个重要的机制在附录文章4还没有体现:线程任务失败后重试、重启线程任务。这个机制在某些开发场景中非常常用,假设从网络中请求数据,但不幸的是网络出现故障,导致在线程体onRun内的代码失败,问题是失败该如何处理?这个时候,常规的做法是自己增加一堆状态字或者返回值加以控制,但是这样无疑使得开发者陷入繁琐的线程状态机的维护中来。
Android Priority Job Queue (Job Manager)完整的解决上上述问题:容错重试回滚任务机制。具体体现在onRun和shouldReRunOnThrowable,如果一个线程任务在onRun里面抛出异常失败,那么将自动进入shouldReRunOnThrowable,然后在shouldReRunOnThrowable会决定是否重试RetryConstraint.RETRY,或者干脆放弃任务RetryConstraint.CANCEL,这里面的重试或者放弃逻辑策略由开发者决定,比如一般的,可以由重试次数决定线程是否还有必要执行,假设一个任务重试了3次仍然不成功,那么就放弃(返RetryConstraint.CANCEL)。一旦放弃后,代码将进入onCanel内,在这里面处理善后事宜,这个机制有些类似Java的try-catch机制。
在附录文章4的基础上,仅仅修改MyJob.java代码演示上述机制:

package zhangphil.app;

import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log; import com.birbit.android.jobqueue.Job;
import com.birbit.android.jobqueue.Params;
import com.birbit.android.jobqueue.RetryConstraint; /**
* Created by Phil on 2016/10/9.
*/
public class MyJob extends Job { private String tag; public MyJob(String tag) {
super(new Params(500).requireNetwork().persist().groupBy(tag));
this.tag = tag;
Log.d(tag, "初始化");
} @Override
public void onAdded() {
Log.d(tag, "添加任务");
} //在这里面放置耗时的后台线程化任务
@Override
public void onRun() throws Throwable {
Log.d(tag, "开始运行..."); SystemClock.sleep(2000); //此处抛出异常后,jobqueue将立即自动进入shouldReRunOnThrowable
throw new Exception(); //Log.d(tag, "完成");
} @Override
protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) {
// An error occurred in onRun.
// Return value determines whether this job should retry or cancel. You can further
// specify a backoff strategy or change the job's priority. You can also apply the
// delay to the whole group to preserve jobs' running order. Log.d(tag, "runCount: " + runCount + " maxRunCount: " + maxRunCount); //如果重试了3次仍未成功,那么就放弃执行任务
if (runCount == 3)
return RetryConstraint.CANCEL; //这样的返回将导致onRun方法的再次执行,重试,重试将导致代码再次进入onRun。同时,runCount自加1
return RetryConstraint.RETRY;
} //如果重试超过限定次数,将onCancel.
//如果用户主动放弃删掉这个任务,也一样进入onCancel
@Override
protected void onCancel(int cancelReason, @Nullable Throwable throwable) {
Log.d(tag, "cancelReason:" + cancelReason);
}
}

代码运行后Logcat完整输出:

10-10 15:51:39.488 16856-16856/zhangphil.app D/任务1: 初始化
10-10 15:51:39.488 16856-16856/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] post message com.birbit.android.jobqueue.messaging.message.AddJobMessage@b1a3ff0
10-10 15:51:39.488 16856-16856/zhangphil.app D/Activity: performCreate Call Injection manager
10-10 15:51:39.488 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085899495109636
10-10 15:51:39.488 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085899495109636
10-10 15:51:39.488 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:39.488 16856-17353/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] remove message com.birbit.android.jobqueue.messaging.message.AddJobMessage@b1a3ff0
10-10 15:51:39.488 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] consuming message of type ADD_JOB
10-10 15:51:39.488 16856-16856/zhangphil.app I/InjectionManager: dispatchOnViewCreated > Target : zhangphil.app.MainActivity isFragment :false
10-10 15:51:39.528 16856-17353/zhangphil.app D/zhangphil job: added job class: MyJob priority: 500 delay: 0 group : 任务1 persistent: true
10-10 15:51:39.528 16856-17353/zhangphil.app D/任务1: 添加任务
10-10 15:51:39.528 16856-17353/zhangphil.app D/zhangphil job: considering adding a new consumer. Should poke all waiting? false isRunning? true waiting workers? 0
10-10 15:51:39.528 16856-17353/zhangphil.app D/zhangphil job: check above load factor: totalCons:0 minCons:1 maxConsCount: 3, loadFactor 3 remainingJobs: 1 running holders: 0. isAbove:true
10-10 15:51:39.528 16856-17353/zhangphil.app D/zhangphil job: nothing has been poked. are we above load factor? true
10-10 15:51:39.528 16856-17353/zhangphil.app D/zhangphil job: adding another consumer
10-10 15:51:39.538 16856-16856/zhangphil.app D/SecWifiDisplayUtil: Metadata value : SecSettings2
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085899551798802
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085899551798802
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:39.548 16856-16856/zhangphil.app D/ViewRootImpl: #1 mView = com.android.internal.policy.PhoneWindow$DecorView{8602777 I.E...... R.....ID 0,0-0,0}
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] remove message null
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: joq idle. running:? true
10-10 15:51:39.548 16856-17358/zhangphil.app D/zhangphil job: flushing messages at time 1476085899553556250
10-10 15:51:39.548 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] remove message null
10-10 15:51:39.548 16856-17358/zhangphil.app D/zhangphil job: consumer manager on idle
10-10 15:51:39.548 16856-17358/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] post message com.birbit.android.jobqueue.messaging.message.JobConsumerIdleMessage@a013fe4
10-10 15:51:39.548 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] will wait on the lock forever
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: Job queue idle. next job at: -9223372036854775808
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: add delayed message com.birbit.android.jobqueue.messaging.message.ConstraintChangeMessage@257dc4d at time -9223372036854775808
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] did on idle post a message? true
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085899555766615
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085899555766615
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [queue_CONSTRAINT_CHANGE_5] post message com.birbit.android.jobqueue.messaging.message.ConstraintChangeMessage@257dc4d
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [queue_CONSTRAINT_CHANGE_5] remove message com.birbit.android.jobqueue.messaging.message.ConstraintChangeMessage@257dc4d
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] consuming message of type CONSTRAINT_CHANGE
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: considering adding a new consumer. Should poke all waiting? true isRunning? true waiting workers? 0
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: check above load factor: totalCons:1 minCons:1 maxConsCount: 3, loadFactor 3 remainingJobs: 1 running holders: 0. isAbove:false
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: nothing has been poked. are we above load factor? false
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085899559063386
10-10 15:51:39.548 16856-17359/zhangphil.app D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085899559063386
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [queue_CONSTRAINT_CHANGE_5] remove message null
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] remove message null
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] remove message com.birbit.android.jobqueue.messaging.message.JobConsumerIdleMessage@a013fe4
10-10 15:51:39.548 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] consuming message of type JOB_CONSUMER_IDLE
10-10 15:51:39.558 16856-16856/zhangphil.app W/ActivityThread: AppLock checkAppLockState isAppLocked = false pkgName = zhangphil.app showWhenLocked = false
10-10 15:51:39.568 16856-17353/zhangphil.app D/zhangphil job: [consumer_3] post message com.birbit.android.jobqueue.messaging.message.RunJobMessage@725c413
10-10 15:51:39.568 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085899571643802
10-10 15:51:39.568 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085899571643802
10-10 15:51:39.568 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:39.568 16856-17353/zhangphil.app D/zhangphil job: [queue_CONSTRAINT_CHANGE_5] remove message null
10-10 15:51:39.568 16856-17353/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] remove message null
10-10 15:51:39.568 16856-17353/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] remove message null
10-10 15:51:39.568 16856-17353/zhangphil.app D/zhangphil job: joq idle. running:? true
10-10 15:51:39.568 16856-17358/zhangphil.app D/zhangphil job: flushing messages at time 1476085899571733438
10-10 15:51:39.568 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] remove message com.birbit.android.jobqueue.messaging.message.RunJobMessage@725c413
10-10 15:51:39.568 16856-17358/zhangphil.app D/zhangphil job: running job JobHolder
10-10 15:51:39.568 16856-17358/zhangphil.app D/zhangphil job: running job MyJob
10-10 15:51:39.568 16856-17358/zhangphil.app D/任务1: 开始运行...
10-10 15:51:39.568 16856-17353/zhangphil.app D/zhangphil job: Job queue idle. next job at: null
10-10 15:51:39.568 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] did on idle post a message? false
10-10 15:51:39.588 16856-17359/zhangphil.app I/Adreno: QUALCOMM build : 0039a8c, I5bc0f577f9
Build Date : 08/03/16
OpenGL ES Shader Compiler Version: XE031.08.00.02
Local Branch :
Remote Branch : refs/tags/AU_LINUX_ANDROID_LA.HB.1.1.1.C1.06.00.00.165.223
Remote Branch : NONE
Reconstruct Branch : NOTHING
10-10 15:51:39.588 16856-17359/zhangphil.app D/libEGL: eglInitialize EGLDisplay = 0x7f93bfa188
10-10 15:51:39.588 16856-17359/zhangphil.app I/OpenGLRenderer: Initialized EGL, version 1.4
10-10 15:51:39.618 16856-16856/zhangphil.app D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 96 - 0, 0) vi=Rect(0, 96 - 0, 0) or=1
10-10 15:51:39.628 16856-16856/zhangphil.app W/DisplayListCanvas: DisplayListCanvas is started on unbinded RenderNode (without mOwningView)
10-10 15:51:39.668 16856-16856/zhangphil.app I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@87b6b1c time:249284264
10-10 15:51:41.568 16856-17358/zhangphil.app E/zhangphil job: error while executing job zhangphil.app.MyJob@9eb605a
java.lang.Exception
at zhangphil.app.MyJob.onRun(MyJob.java:38)
at com.birbit.android.jobqueue.Job.safeRun(Job.java:229)
at com.birbit.android.jobqueue.JobHolder.safeRun(JobHolder.java:132)
at com.birbit.android.jobqueue.ConsumerManager$Consumer.handleRunJob(ConsumerManager.java:398)
at com.birbit.android.jobqueue.ConsumerManager$Consumer.access$000(ConsumerManager.java:317)
at com.birbit.android.jobqueue.ConsumerManager$Consumer$2.handleMessage(ConsumerManager.java:345)
at com.birbit.android.jobqueue.messaging.SafeMessageQueue.consume(SafeMessageQueue.java:36)
at com.birbit.android.jobqueue.ConsumerManager$Consumer.run(ConsumerManager.java:380)
at java.lang.Thread.run(Thread.java:818)
10-10 15:51:41.568 16856-17358/zhangphil.app D/任务1: runCount: 1 maxRunCount: 20
10-10 15:51:41.568 16856-17358/zhangphil.app D/zhangphil job: safeRunResult for zhangphil.app.MyJob@9eb605a : false. re run:true. cancelled: false
10-10 15:51:41.578 16856-17358/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] post message com.birbit.android.jobqueue.messaging.message.RunJobResultMessage@2fa28b
10-10 15:51:41.578 16856-17358/zhangphil.app D/zhangphil job: flushing messages at time 1476085901581361354
10-10 15:51:41.578 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] remove message null
10-10 15:51:41.578 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085901581436927
10-10 15:51:41.578 16856-17358/zhangphil.app D/zhangphil job: consumer manager on idle
10-10 15:51:41.578 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085901581436927
10-10 15:51:41.578 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:41.578 16856-17353/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] remove message com.birbit.android.jobqueue.messaging.message.RunJobResultMessage@2fa28b
10-10 15:51:41.578 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] consuming message of type RUN_JOB_RESULT
10-10 15:51:41.578 16856-17358/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] post message com.birbit.android.jobqueue.messaging.message.JobConsumerIdleMessage@a013fe4
10-10 15:51:41.578 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] will wait on the lock forever
10-10 15:51:41.598 16856-17353/zhangphil.app D/zhangphil job: reinsert job result true
10-10 15:51:41.598 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085901603381718
10-10 15:51:41.598 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085901603381718
10-10 15:51:41.598 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:41.598 16856-17353/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] remove message null
10-10 15:51:41.598 16856-17353/zhangphil.app D/zhangphil job: [queue_CONSTRAINT_CHANGE_5] remove message null
10-10 15:51:41.598 16856-17353/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] remove message null
10-10 15:51:41.598 16856-17353/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] remove message com.birbit.android.jobqueue.messaging.message.JobConsumerIdleMessage@a013fe4
10-10 15:51:41.598 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] consuming message of type JOB_CONSUMER_IDLE
10-10 15:51:41.608 16856-17353/zhangphil.app D/zhangphil job: [consumer_3] post message com.birbit.android.jobqueue.messaging.message.RunJobMessage@725c413
10-10 15:51:41.608 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085901615635572
10-10 15:51:41.608 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085901615635572
10-10 15:51:41.608 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:41.608 16856-17353/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] remove message null
10-10 15:51:41.608 16856-17353/zhangphil.app D/zhangphil job: [queue_CONSTRAINT_CHANGE_5] remove message null
10-10 15:51:41.608 16856-17353/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] remove message null
10-10 15:51:41.608 16856-17358/zhangphil.app D/zhangphil job: flushing messages at time 1476085901615705104
10-10 15:51:41.608 16856-17353/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] remove message null
10-10 15:51:41.608 16856-17353/zhangphil.app D/zhangphil job: joq idle. running:? true
10-10 15:51:41.608 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] remove message com.birbit.android.jobqueue.messaging.message.RunJobMessage@725c413
10-10 15:51:41.608 16856-17358/zhangphil.app D/zhangphil job: running job JobHolder
10-10 15:51:41.608 16856-17358/zhangphil.app D/zhangphil job: running job MyJob
10-10 15:51:41.608 16856-17358/zhangphil.app D/任务1: 开始运行...
10-10 15:51:41.608 16856-17353/zhangphil.app D/zhangphil job: Job queue idle. next job at: null
10-10 15:51:41.618 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] did on idle post a message? false
10-10 15:51:43.608 16856-17358/zhangphil.app E/zhangphil job: error while executing job zhangphil.app.MyJob@1ef2826
java.lang.Exception
at zhangphil.app.MyJob.onRun(MyJob.java:38)
at com.birbit.android.jobqueue.Job.safeRun(Job.java:229)
at com.birbit.android.jobqueue.JobHolder.safeRun(JobHolder.java:132)
at com.birbit.android.jobqueue.ConsumerManager$Consumer.handleRunJob(ConsumerManager.java:398)
at com.birbit.android.jobqueue.ConsumerManager$Consumer.access$000(ConsumerManager.java:317)
at com.birbit.android.jobqueue.ConsumerManager$Consumer$2.handleMessage(ConsumerManager.java:345)
at com.birbit.android.jobqueue.messaging.SafeMessageQueue.consume(SafeMessageQueue.java:36)
at com.birbit.android.jobqueue.ConsumerManager$Consumer.run(ConsumerManager.java:380)
at java.lang.Thread.run(Thread.java:818)
10-10 15:51:43.608 16856-17358/zhangphil.app D/任务1: runCount: 2 maxRunCount: 20
10-10 15:51:43.608 16856-17358/zhangphil.app D/zhangphil job: safeRunResult for zhangphil.app.MyJob@1ef2826 : false. re run:true. cancelled: false
10-10 15:51:43.608 16856-17358/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] post message com.birbit.android.jobqueue.messaging.message.RunJobResultMessage@2fa28b
10-10 15:51:43.608 16856-17358/zhangphil.app D/zhangphil job: flushing messages at time 1476085903619928280
10-10 15:51:43.608 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] remove message null
10-10 15:51:43.608 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085903620000572
10-10 15:51:43.608 16856-17358/zhangphil.app D/zhangphil job: consumer manager on idle
10-10 15:51:43.608 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085903620000572
10-10 15:51:43.608 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:43.608 16856-17353/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] remove message com.birbit.android.jobqueue.messaging.message.RunJobResultMessage@2fa28b
10-10 15:51:43.618 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] consuming message of type RUN_JOB_RESULT
10-10 15:51:43.618 16856-17358/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] post message com.birbit.android.jobqueue.messaging.message.JobConsumerIdleMessage@a013fe4
10-10 15:51:43.618 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] will wait on the lock forever
10-10 15:51:43.628 16856-17353/zhangphil.app D/zhangphil job: reinsert job result true
10-10 15:51:43.628 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085903636682603
10-10 15:51:43.628 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085903636682603
10-10 15:51:43.628 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:43.628 16856-17353/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] remove message null
10-10 15:51:43.628 16856-17353/zhangphil.app D/zhangphil job: [queue_CONSTRAINT_CHANGE_5] remove message null
10-10 15:51:43.628 16856-17353/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] remove message null
10-10 15:51:43.628 16856-17353/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] remove message com.birbit.android.jobqueue.messaging.message.JobConsumerIdleMessage@a013fe4
10-10 15:51:43.628 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] consuming message of type JOB_CONSUMER_IDLE
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: [consumer_3] post message com.birbit.android.jobqueue.messaging.message.RunJobMessage@725c413
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085903643573436
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085903643573436
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] remove message null
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: [queue_CONSTRAINT_CHANGE_5] remove message null
10-10 15:51:43.638 16856-17358/zhangphil.app D/zhangphil job: flushing messages at time 1476085903643628228
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] remove message null
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] remove message null
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: joq idle. running:? true
10-10 15:51:43.638 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] remove message com.birbit.android.jobqueue.messaging.message.RunJobMessage@725c413
10-10 15:51:43.638 16856-17358/zhangphil.app D/zhangphil job: running job JobHolder
10-10 15:51:43.638 16856-17358/zhangphil.app D/zhangphil job: running job MyJob
10-10 15:51:43.638 16856-17358/zhangphil.app D/任务1: 开始运行...
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: Job queue idle. next job at: null
10-10 15:51:43.638 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] did on idle post a message? false
10-10 15:51:45.638 16856-17358/zhangphil.app E/zhangphil job: error while executing job zhangphil.app.MyJob@12572bd
java.lang.Exception
at zhangphil.app.MyJob.onRun(MyJob.java:38)
at com.birbit.android.jobqueue.Job.safeRun(Job.java:229)
at com.birbit.android.jobqueue.JobHolder.safeRun(JobHolder.java:132)
at com.birbit.android.jobqueue.ConsumerManager$Consumer.handleRunJob(ConsumerManager.java:398)
at com.birbit.android.jobqueue.ConsumerManager$Consumer.access$000(ConsumerManager.java:317)
at com.birbit.android.jobqueue.ConsumerManager$Consumer$2.handleMessage(ConsumerManager.java:345)
at com.birbit.android.jobqueue.messaging.SafeMessageQueue.consume(SafeMessageQueue.java:36)
at com.birbit.android.jobqueue.ConsumerManager$Consumer.run(ConsumerManager.java:380)
at java.lang.Thread.run(Thread.java:818)
10-10 15:51:45.638 16856-17358/zhangphil.app D/任务1: runCount: 3 maxRunCount: 20
10-10 15:51:45.638 16856-17358/zhangphil.app D/zhangphil job: safeRunResult for zhangphil.app.MyJob@12572bd : false. re run:false. cancelled: false
10-10 15:51:45.638 16856-17358/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] post message com.birbit.android.jobqueue.messaging.message.RunJobResultMessage@2fa28b
10-10 15:51:45.638 16856-17358/zhangphil.app D/zhangphil job: flushing messages at time 1476085905647085571
10-10 15:51:45.638 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] remove message null
10-10 15:51:45.638 16856-17358/zhangphil.app D/zhangphil job: consumer manager on idle
10-10 15:51:45.638 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085905647246300
10-10 15:51:45.638 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085905647246300
10-10 15:51:45.638 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:45.638 16856-17353/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] remove message com.birbit.android.jobqueue.messaging.message.RunJobResultMessage@2fa28b
10-10 15:51:45.638 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] consuming message of type RUN_JOB_RESULT
10-10 15:51:45.638 16856-17353/zhangphil.app D/任务1: cancelReason:5
10-10 15:51:45.638 16856-17358/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] post message com.birbit.android.jobqueue.messaging.message.JobConsumerIdleMessage@a013fe4
10-10 15:51:45.638 16856-17358/zhangphil.app D/zhangphil job: [consumer_3] will wait on the lock forever
10-10 15:51:45.658 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085905666501300
10-10 15:51:45.658 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085905666501300
10-10 15:51:45.658 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:45.658 16856-17353/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] remove message null
10-10 15:51:45.658 16856-17353/zhangphil.app D/zhangphil job: [queue_CONSTRAINT_CHANGE_5] remove message null
10-10 15:51:45.658 16856-17353/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] remove message null
10-10 15:51:45.658 16856-17353/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] remove message com.birbit.android.jobqueue.messaging.message.JobConsumerIdleMessage@a013fe4
10-10 15:51:45.658 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] consuming message of type JOB_CONSUMER_IDLE
10-10 15:51:45.668 16856-17353/zhangphil.app D/zhangphil job: keep alive: 1476086025647041248
10-10 15:51:45.668 16856-17353/zhangphil.app D/zhangphil job: Consumer idle, will kill? false . isRunning: true
10-10 15:51:45.668 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] looking for next message at time 1476085905680193019
10-10 15:51:45.668 16856-17353/zhangphil.app D/zhangphil job: flushing messages at time 1476085905680193019
10-10 15:51:45.668 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] next delayed job null
10-10 15:51:45.668 16856-17353/zhangphil.app D/zhangphil job: [queue_RUN_JOB_RESULT_6] remove message null
10-10 15:51:45.678 16856-17353/zhangphil.app D/zhangphil job: [queue_CONSTRAINT_CHANGE_5] remove message null
10-10 15:51:45.678 16856-17353/zhangphil.app D/zhangphil job: [queue_ADD_JOB_2] remove message null
10-10 15:51:45.678 16856-17353/zhangphil.app D/zhangphil job: [queue_JOB_CONSUMER_IDLE_4] remove message null
10-10 15:51:45.678 16856-17353/zhangphil.app D/zhangphil job: joq idle. running:? true
10-10 15:51:45.678 16856-17353/zhangphil.app D/zhangphil job: Job queue idle. next job at: null
10-10 15:51:45.678 16856-17353/zhangphil.app D/zhangphil job: [priority_mq] did on idle post a message? false

上述完整Logcat输出显示了代码在onRun里面抛出异常然后容错回滚机制发挥作用重启了任务,过滤“任务”后精简的关键Logcat输出:

10-10 15:51:39.488 16856-16856/zhangphil.app D/任务1: 初始化
10-10 15:51:39.528 16856-17353/zhangphil.app D/zhangphil job: added job class: MyJob priority: 500 delay: 0 group : 任务1 persistent: true
10-10 15:51:39.528 16856-17353/zhangphil.app D/任务1: 添加任务
10-10 15:51:39.568 16856-17358/zhangphil.app D/任务1: 开始运行...
10-10 15:51:41.568 16856-17358/zhangphil.app D/任务1: runCount: 1 maxRunCount: 20
10-10 15:51:41.608 16856-17358/zhangphil.app D/任务1: 开始运行...
10-10 15:51:43.608 16856-17358/zhangphil.app D/任务1: runCount: 2 maxRunCount: 20
10-10 15:51:43.638 16856-17358/zhangphil.app D/任务1: 开始运行...
10-10 15:51:45.638 16856-17358/zhangphil.app D/任务1: runCount: 3 maxRunCount: 20
10-10 15:51:45.638 16856-17353/zhangphil.app D/任务1: cancelReason:5

附录:
【1】《Java线程池:ExecutorService,Executors》链接地址:http://blog.csdn.net/zhangphil/article/details/43898637  
【2】《Java线程池及Future、Callable获得线程返回结果【Java线程池系列2】》链接地址:http://blog.csdn.net/zhangphil/article/details/49701219
【3】《Java线程池之FutureTask【Java线程池系列3】》链接地址:http://blog.csdn.net/zhangphil/article/details/49702751
【4】《Android Priority Job Queue (Job Manager)(一)》链接地址:http://blog.csdn.net/zhangphil/article/details/52777196

Android Priority Job Queue (Job Manager):线程任务的容错重启机制(二)的更多相关文章

  1. Android Priority Job Queue (Job Manager):后台线程任务结果传回前台(三)

     Android Priority Job Queue (Job Manager):后台线程任务结果传回前台(三) 在附录文章4,5的基础上改造MainActivity.java和MyJob.ja ...

  2. Android Priority Job Queue (Job Manager):多重不同Job并发执行并在前台获得返回结果(四)

     Android Priority Job Queue (Job Manager):多重不同Job并发执行并在前台获得返回结果(四) 在Android Priority Job Queue (Jo ...

  3. Android Priority Job Queue (Job Manager)(一)

     Android Priority Job Queue (Job Manager)(一) 一.为什么要引入Android Priority Job Queue (Job Manager)?如今的A ...

  4. 案例复现,带你分析Priority Blocking Queue比较器异常导致的NPE问题

    摘要:本文通过完整的案例复现来演示在什么情况会触发该问题,同时给出了处理建议.希望读者在编程时加以借鉴,避免再次遇到此类问题. 本文分享自华为云社区<Priority Blocking Queu ...

  5. Android的UI设计与后台线程交互

    本文将讨论Android应用程序的线程模型以及如何使用线程来处理耗时较长的操作,而不是在主线程中执行,保证用户界面(UI)的流畅运行.本文还将阐述一些用户界面(UI)中与线程交互的API.UI用户界面 ...

  6. Android开发UI之在子线程中更新UI

    转自第一行代码-Android Android是不允许在子线程中进行UI操作的.在子线程中去执行耗时操作,然后根据任务的执行结果来更新相应的UI控件,需要用到Android提供的异步消息处理机制. 代 ...

  7. Android网络(4):HttpClient必经之路----使用线程安全的单例模式HttpClient,及HttpClient和Application的融合

    上文简介了HttpClient和Tomcatserver的交互,主角是HttpClient,然后它跟server交互有两种方式即get和post.所以这个HttpClient就相似于电脑上用的浏览器. ...

  8. 基于队列queue实现的线程池

    本文通过文章同步功能推送至博客园,显示排版可能会有所错误,请见谅! 写在前文:在Python中给多进程提供了进程池类,对于线程,Python2并没有直接提供线程池类(Python3中提供了线程池功能) ...

  9. Android进阶——多线程系列之四大线程池的使用介绍

    线程池一直是初学者最抵触的东西,由于刚开始学习做项目并不会涉及到线程池的使用,但是不去学习它,心里又好像有个石头一直沉着,一直放心不下,其实是很简单的东西,早晚都要学,不如趁现在吧.由于文章从初学者的 ...

随机推荐

  1. web标准常见问题整理

    1.超链接访问过后hover样式就不出现的问题 2.FF下如何使连续长字段自动换行 3.ff下为什么父容器的高度不能自适应 4. IE6的双倍边距BUG 5. IE6下绝对定位的容器内文本无法正常选择 ...

  2. Spring Web Flow 简介

    Spring Web Flow 简介 博客分类: 转载 SSH 最近在TSS上看到了一片介绍Spring Web Flow的文章,顺便就翻译了下来,SWF的正式版估计要到6月份才能看到了,目前的例子都 ...

  3. ABAP_常用函数整理_傻X版

    输出前导0:CONVERSION_EXIT_ALPHA_INPUT 单位转换:CONVERSION_EXIT_CUNIT_INPUT 单位换算:UNIT_CONVERSION_SIMPLE 修改订单组 ...

  4. Nginx+Php-fpm+MySQL+Redis源代码编译安装指南

    说明:本教程主要包括以下三个部分: 1. 源代码编译安装Nginx 2. 源代码编译安装php以及mysql.redis扩展模块 3. 配置虚拟主机 文中所涉及安装包程序均提供下载链接,欢迎使用 运行 ...

  5. mustache模板技术

    一.简介Web 模板引擎是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,通常是标准的 HTML 文档.当然不同的开发语言有不同模板引擎,如 Javascript 下的 Hog ...

  6. Go语言并发与并行学习笔记(三)

    转:http://blog.csdn.net/kjfcpua/article/details/18265475 Go语言并发的设计模式和应用场景 以下设计模式和应用场景来自Google IO上的关于G ...

  7. 盘点:崛起中的九大HTML5开发工具

    HTML5被看做是Web开发者创建流行Web应用的利器,增加了对视频和Canvas 2D的支持.HTML5的诞生还让人们重新审视浏览器专用多媒体插件的未来,如Adobe的Flash和微软的Silver ...

  8. 强大的Resharp插件

    使用VS有段时间了,一直深深的折服于其强大的功能.之前一直听说有Resharp这个工具,小猪一直也没有太在意.直到今天…… 下载安装: http://www.jetbrains.com/resharp ...

  9. HTTP(socket)下载遇到valgrind提示的错误: Conditional jump or move depends on uninitialised value(s)

    我写了个http下载函数,下载txt.jpg都正常,就是下载php有问题:valgrind会报错Conditional jump or move depends on uninitialised va ...

  10. model.addAttribute("student",student)——渲染

    往前台视图传参数,(将在处理器传入的模型数据在视图jsp中展示出来,即为渲染) 按照spring一般的编码习惯,model 应该是contrller里面的Map结构吧.Map里面添加key=" ...