## xUtils中的任务和回调接口
任务和回调是网络请求的基础接口, xUtils的任务接口支持异步和同步任务的实现.

1. 为什么要设计新的接口, 而不使用Android系统API `AsyncTask`?
    原因有几个方面, AsyncTask在各个版本系统中表现不一致, 包括默认任务的并发数, 是否可在子线程中使用等.
2. xUtils中的任务和回调接口特点是什么?
    * 可以在任何线程中直接使用.
    * 支持设置优先级.
    * 支持异步调用和同步调用.
    * 默认支持FIFO和FILO, 也可以使用自定义Executor.
    * 异步任务中所有错误(包括异步过程和回调操作)都会进入onError, onFinished任何情况总是会被调用, 安全可靠.

3. 使用xUtils中的任务使用
```java
x.task().start(task); // 执行一个异步任务
result = x.task().startSync(task); // 同步执行该任务
```
看到上面的接口是不是很简单, 定义一个任务后可以很方便的异步执行或同步执行. 接下来我们开始接受怎样定义一个任务.
```java
// task的hello world
x.task().start(new AbsTask<String>() {
    @Override
    protected String doBackground() throws Throwable {
        return "hello world!";
    }

    @Override
    protected void onSuccess(String result) {
        Log.d("test", result);
    }

    @Override
    protected void onError(Throwable ex, boolean isCallbackError) {
        Log.e("test", ex.getMessage(), ex);
    }

    @Override
    protected void onFinished() {
        Log.d("test", "finished");
    }
});
```
实例中使用task的基类AbsTask定义了一个task的实例,
并使用异步的方式调用, `doBackground`在默认线程池中进行(后面会介绍怎样自定义线程池).
`start`的返回值类型为`AbsTask<T>`(示例中T为String),
但它并非被执行的task的实例, 而是task的代理, 对代理实例的所有方法调用不必关心线程的问题, 框架会自动处理.
如果使用`startSync`执行这个任务, 则`doBackground`在当前线程同步执行, 并且`doBackground`的返回值作为`startSync`的返回值.

4. AbsTask的重要属性和方法(以`on`开头的方法为UI线程的回调方法, 简称`回调方法`)
    * `doBackground` 执行任务的主要过程, 上面已经介绍了它的特性, 虽然它可以同步执行但仍然被这样命名.
    * `onWaiting` 任务`start`或`startSync`之后会立即执行, 任务尚未被分配执行线程.
    * `onStarted` 任务被分配执行线程后立即执行, 接下来会执行`doBackground`.
    * `onSuccess` 在`doBackground`执行完成后立即执行.
    * `onCancelled` 任务`onSuccess`之前任何线程调用`AbsTask#cancel`或`doBackground`中抛出`CancelledException`之后执行.
    * `onUpdate(int flag, Object... args)` 任何线程调用了`AbsTask#update(int flag, Object... args)`之后执行.
    * `onError(Throwable ex, boolean isCallbackError)` 以上任何方法中出现异常时执行, 参数isCallbackError表示是否`回调方法`中的错误.
    * `onFinished` 总是在最终调用, 即使任务出现error会被cancel.

5. 取消任务 AbsTask#cancel()
示例:
```java
AbsTask<?> proxy = x.task().start(task);
...
proxy.cancel(); // 在任何线程调用
// 如果在任务内部取消, 建议使用抛出CancelledException的方法, 这样可以使用message或自定义的CancelledException表明取消的原因.
...
```

6. 自定义更新通知 AbsTask#update(int flag, Object... args)
示例:
```java
x.task().start(new AbsTask<String>() {

    private static final int FLAG_UPDATE = 1;

    @Override
    protected String doBackground() throws Throwable {
        this.update(FLAG_UPDATE, 0);
        ...
        this.update(FLAG_UPDATE, 50);
        ...
        this.update(FLAG_UPDATE, 100);
        return "hello world!";
    }

    @Override
    protected void onUpdate(int flag, Object... args) {
        switch (flag) {
            case FLAG_UPDATE: {
                if (args == null || args.length != 1) return;
                int value = (Integer) args[0];
                ...
                break;
            }
            default: {
                break;
            }
        }
    }

    ...
});
```

7. 设置优先级, 覆盖方法 AbsTask#getPriority

8. 设置自定义线程池, 覆盖方法 AbsTask#getExecutor

9. 取消任务时是否不等待任务彻底结束, 立即收到取消的通知, 覆盖方法 AbsTask#isCancelFast

10. 任务是否被取消 `final` AbsTask#isCancelled,

11. 任务是都已经执行完成 `final` AbsTask#isFinished

12. 获取任务的状态 `final` AbsTask#getState

13. 获取执行结果 `final` AbsTask#getResult

14. 其他, 使用AbsTask(Callback.Cancelable cancelHandler)构造函数可自定义可扩展的取消逻辑.