2017-10-16 19 views
0

Bolts Task 프레임 워크에 대한 설명서를 이해하는 데 문제가 있습니다. 더 복잡한 작업을 작성해야하는 복잡한 Android 프로젝트에서 이것을 많이 사용하고 있습니다. TaskCompletionSource과 함께이 작업을 수행 할 수 있으므로 작업 결과를 설정할 수 있습니까? 백그라운드에서 실행될 코드는 어디에 두어야합니까? 내가 사용하고 작업의 예Android Bolts Task : 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 개체를 완전히 피하고 작업 결과가 포함 된 사용자 지정 Task State 개체를 사용자 지정 isError 및 Exception 속성과 함께 반환하는 것입니다. 그러나 이것은 TaskCompletionSource를 사용하는 것만 큼 우아하지 않습니다.

답변

1

발생하는 문제는 #continueWith(Continuation) 대신 #onSuccess(Continuation)을 사용하고있는 것 같습니다. onSuccessContinuation은 원본 작업이 성공적으로 해결 될 때만 호출됩니다. continueWith으로 변경하면 소스 작업이 성공, 실패 또는 취소로 해결 될 때 Continuation이 호출됩니다.

+1

네가 맞아, 고마워! –