最近在做的一個需求被產品的各種奇葩要求和各種為了體驗的迷之借口搞得面目前非,里面有很多異步請求,而且有時候是獨立執行,有時候需要相互依賴的串行執行(A的結果回來了,成功的話執行B,不成功不管)。一開始我都是非常簡單的在Activity中實現各種回調接口,然后在回調方法中調用下一個異步請求,為了能串行的執行,因此加了很多boolean值標記當前什么狀態。然后我就想做一個可以封裝異步任務,然后按照順序異步執行的一個模式。
我希望使用的時候,可以new一個AsyncTask對象,然后它成功的后執行什么,失敗的后執行什么這樣封裝好。用起來大概是這個樣子:
1 TaskA taskA = new TaskA(); 2 TaskB taskB = new TaskB(); 3 TaskC taskC = new TaskC(); 4 taskA.success(tastB).failure(taskC);
於是我就寫了一個這樣的東西:
public abstract class AsyncTask { private static final int EXEC_TYPE_TASK = 1; private static final int EXEC_TYPE_RUNNABLE = 2; private int mAfterSuccessExecWhat = EXEC_TYPE_TASK; private int mAfterFailureExecWhat = EXEC_TYPE_TASK; private AsyncTask mAfterSuccessTask = null; private AsyncTask mAfterFailureTask = null; private Runnable mAfterSuccessRunnable = null; private Runnable mAfterFailureRunnable = null; public final void start() { onBegin(); onWork(); } protected void onBegin() { } protected abstract void onWork(); protected void onEndSuccess(Object ... object) { switch (mAfterSuccessExecWhat) { case EXEC_TYPE_TASK: if (mAfterSuccessTask != null) { mAfterSuccessTask.start(); } break; case EXEC_TYPE_RUNNABLE: if (mAfterSuccessRunnable != null) { mAfterSuccessRunnable.run(); } break; } } protected void onEndFailure(Object ... object) { switch (mAfterFailureExecWhat) { case EXEC_TYPE_TASK: if (mAfterFailureTask != null) { mAfterFailureTask.start(); } break; case EXEC_TYPE_RUNNABLE: if (mAfterFailureRunnable != null) { mAfterFailureRunnable.run(); } break; } } public final AsyncTask afterSuccessExec(AsyncTask nextTask) { mAfterSuccessTask = nextTask; mAfterSuccessExecWhat = EXEC_TYPE_TASK; return this; } public final AsyncTask afterFailureExec(AsyncTask nextTask) { mAfterFailureTask = nextTask; mAfterFailureExecWhat = EXEC_TYPE_TASK; return this; } public final AsyncTask afterSuccessRun(Runnable runnable) { mAfterSuccessRunnable = runnable; mAfterSuccessExecWhat = EXEC_TYPE_RUNNABLE; return this; } public final AsyncTask afterFailureRun(Runnable runnable) { mAfterFailureRunnable = runnable; mAfterFailureExecWhat = EXEC_TYPE_RUNNABLE; return this; } }
然后,假設有兩個任務,一個是檢測異常,就是傳一些參數,然后發起一個網絡請求,讓后台的邏輯來判斷是否異常並且返回。另一個是發起一個創建請求。這些屬於業務邏輯部分,就簡單的寫下。
public class YourEngine { interface OnExceptionResultCallback { void onResult(int errorCode); } interface OnCreateAttendanceResultCallback { void onResult(int errorCode); } public static void requestException(int data, OnExceptionResultCallback callback) { System.out.println("開始檢測異常"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("網絡回調過來"); if (data == 100) { if (callback != null) { callback.onResult(0); } } else { if (callback != null) { callback.onResult(1); } } } public static void requestCreateAttendance(int data, OnCreateAttendanceResultCallback callback) { System.out.println("開始創建考勤"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("網絡回調過來"); if (data == 100) { if (callback != null) { callback.onResult(0); } } else { if (callback != null) { callback.onResult(1); } } } }
然后,接下來有兩種場景,第一種是檢測異常的請求可以單獨發送。另一種是先發送檢測異常的請求,如果返回成功,那么再發送創建考勤的請求,否則的話則什么都不干。
如果按原始的方式來搞,我需要在第一個回調中做判斷是否需要進行下一個異步任務。這樣就比較惡心了,一堆布爾值很煩。
所以,搞出了上面這個AsyncTask之后,工作就簡單了。用起來的時候,就像這樣:
CheckExceptionTask checkExceptionTask = new CheckExceptionTask(); CreateAttendanceTask createTask = new CreateAttendanceTask(); checkExceptionTask.afterSuccessExec(createTask).afterFailureExec(null); checkExceptionTask.start();
這樣就是基本的一個實現,用起來就爽了。