Задача 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
будет вызван, когда исходная задача преобразуется в успех, неудачу или отменена.