2017-10-16 136 views
0

我遇到的問題了解有關Bolts任務框架的文檔。我在一個複雜的Android項目中大量使用它,這需要編寫更復雜的任務。我怎樣才能實現這一點TaskCompletionSource所以我可以設置任務的結果? 在哪裏放置要在後臺執行的代碼?任務的例子Android Bolts任務:與TaskCompletionSource分開的類中的複雜任務

一個草案,我使用:

public class CheckInternetConnectionTask { 
    private static final String TAG     = "CheckInternetConnReq"; 
    private static  Date mLastCheckDate  = null; 
    private static  Boolean mLastConnectionStatus = null; 
    private static  int  mConnectionAttempts = 0; 

    private Context mContext; 

    public CheckInternetConnectionTask(Context context) { 
     this.mContext = context; 
    } 

    public void resetConnectionStatus() { 
     mLastCheckDate = null; 
     mLastConnectionStatus = null; 
     mConnectionAttempts = 0; 
    } 

    public Task<Boolean> getTask() { 
     return Task.callInBackground(new Callable<Boolean>() { 
      @Override 
      public Boolean call() throws Exception { 
       Log.i(TAG, "Checking for internet connection..."); 
       Calendar calendar = Calendar.getInstance(); 

       Date currentDate = calendar.getTime(); 

       if (mLastCheckDate == null) { 
        mLastCheckDate = calendar.getTime(); 
       } 

       if (mLastConnectionStatus != null && getDifferenceInSeconds(currentDate, mLastCheckDate) < 5) { 
        Log.i(TAG, "Last checked < 5 seconds, returning previous value: " + mLastConnectionStatus); 
        if (mConnectionAttempts < 10) { 
         mConnectionAttempts ++; 

         return mLastConnectionStatus; 
        } 

        Log.i(TAG, "Resetting connection check attempt counter to 0, checking for internet connection..."); 
        mConnectionAttempts = 0; 
       } 

       ConnectionDetector connectionDetector = new ConnectionDetector(mContext); 

       mLastCheckDate = currentDate; 
       mLastConnectionStatus = connectionDetector.isConnected(); 

       return mLastConnectionStatus; 
      } 
     }); 
    } 

    private long getDifferenceInSeconds(Date currentDate, Date savedDate) { 
     long diffInMillisec = currentDate.getTime() - savedDate.getTime(); 

     return TimeUnit.MILLISECONDS.toSeconds(diffInMillisec) % 60; 
    } 
} 

假設上面的類是在我的代碼中使用,則調用是:

final CheckInternetConnectionTask checkConectionTask = new CheckInternetConnectionTask(this); 
checkConectionTask.getTask().onSuccess(new Continuation<Boolean, Object>() { 
    @Override 
    public Object then(Task<Boolean> task) throws Exception { 
     // This can never be used: 
     if (task.isFaulted()) { 
      // TODO: Notify user that something went wrong 
     } else {   
      mCardNoConnection.setVisibility(task.getResult() ? View.GONE : View.VISIBLE); 
     } 
     return null; 
    } 
}, Task.UI_THREAD_EXECUTOR); 

這樣我無法訪問task.getError()方法,因爲沒有定義完成源。 如果我在自己的類中有複雜對象,我該如何正確使用這個框架?

另一種選擇是完全避免TaskCompletionSource對象並返回某種自定義任務狀態對象,該對象將包含任務結果以及自定義的isError和Exception屬性。但是這不像使用TaskCompletionSource那樣優雅。

回答

1

看來您遇到的問題是您正在使用#onSuccess(Continuation)而不是#continueWith(Continuation)。只有在源任務成功解析時纔會調用onSuccessContinuation。如果將其更改爲continueWith,則當源任務解析爲成功,失敗或取消時,將調用Continuation

+1

你是對的,謝謝! –