Задача Android Bolts: сложная задача в отдельном классе с помощью TaskCompletionSource

У меня возникли проблемы с пониманием документации по структуре задач Bolts. Я активно использую это в сложном проекте 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 и вернуть какой-то пользовательский объект "Состояние задачи", который будет содержать результат задачи, а также настраиваемые свойства isError и Exception. Но это не так элегантно, как использование TaskCompletionSource.

1 ответ

Решение

Кажется, проблема в том, что вы используете #onSuccess(Continuation) вместо #continueWith(Continuation), onSuccess"s Continuation будет вызываться только после успешного разрешения исходной задачи. Если вы измените его на continueWith, Continuation будет вызван, когда исходная задача преобразуется в успех, неудачу или отменена.

Другие вопросы по тегам