【问题标题】:Android Bolts Task: Complex Task in separate class with TaskCompletionSourceAndroid Bolts 任务:具有 TaskCompletionSource 的单独类中的复杂任务
【发布时间】:2017-10-16 14:30:40
【问题描述】:

我在理解有关 Bolts Task 框架的文档时遇到问题。我在一个需要编写更复杂任务的复杂 Android 项目中大量使用它。我怎样才能与 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 优雅。

【问题讨论】:

    标签: android task bolts-framework


    【解决方案1】:

    您遇到的问题似乎是您使用的是#onSuccess(Continuation) 而不是#continueWith(Continuation)onSuccessContinuation 只会在源任务成功解析时被调用。如果将其更改为continueWith,则在源任务解析为成功、失败或取消时将调用Continuation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 2016-12-06
      相关资源
      最近更新 更多