/** * Cancel execution if possible. This is called on the Worker thread * * <p>Do not override this unless you also call super.cancel(boolean). * * <p>Override onCanceled() is the normal notification location, and is called from the UI thread * with Task state updates handled for you. * * @param mayInterruptIfRunning (not yet supported) * @return */ public synchronized boolean cancel(final boolean mayInterruptIfRunning) { boolean canceled = false; // #debug L.i("Begin explicit cancel task", "status=" + this.getStatusString() + " " + this); switch (status) { case EXEC_STARTED: if (mayInterruptIfRunning && Worker.interruptWorkable(this)) { setStatus(CANCELED); canceled = true; } break; case EXEC_FINISHED: case UI_RUN_FINISHED: // #debug L.i( "Attempt to cancel Task after run completes, suspicious but may be normal", this.toString()); break; default: setStatus(CANCELED); canceled = true; } return canceled; }
/** * You can call this as the return statement of your overriding method once you have set the * result * * @return */ public final Object exec(Object in) { Object out = in; try { synchronized (this) { if (in == null) { in = value; } else { value = in; } if (status == Task.CANCELED || status == Task.EXCEPTION) { throw new IllegalStateException( this.getStatusString() + " state can not be executed: " + this); } else if (status != Task.EXEC_STARTED) { setStatus(Task.EXEC_STARTED); } } out = doInBackground(in); final boolean doRun; final Task t; synchronized (this) { value = out; doRun = status == EXEC_STARTED; if (doRun) { setStatus(EXEC_FINISHED); } t = chainedTask; } if (this instanceof UITask && doRun) { PlatformUtils.runOnUiThread((UITask) this); } if (t != null) { // #debug L.i("Begin exec chained task", chainedTask.toString() + " INPUT: " + out); t.exec(out); // #debug L.i("End exec chained task", chainedTask.toString()); } } catch (final Throwable t) { // #debug L.e("Unhandled task exception", this.toString(), t); setStatus(EXCEPTION); } return out; }
/** * Check status of the object to ensure it can be queued at this time (it is not already queued * and running) * * @throws IllegalStateException if the task is currently queued or currently running */ public synchronized void notifyTaskForked() throws IllegalStateException { if (status < EXEC_FINISHED || (this instanceof Runnable && status < UI_RUN_FINISHED)) { throw new IllegalStateException( "Task can not be re-forked, wait for previous exec to complete: status=" + getStatusString()); } setStatus(EXEC_PENDING); }