Android Bolts 任务:复杂任务与 TaskCompletionSource 分开 class
Android Bolts Task: Complex Task in separate class with 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;
}
}
假设我的代码中使用了上面的class,那么调用就是:
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() 方法,因为没有定义完成源。
如果我在自己的 classes 中有复杂的对象,我该如何正确使用这个框架?
另一种选择是完全避免 TaskCompletionSource 对象和 return 某种自定义任务状态对象,该对象将包含任务结果以及自定义 isError 和 Exception 属性。但这并不像使用 TaskCompletionSource 那样优雅。
您遇到的问题似乎是您使用的是 #onSuccess(Continuation)
而不是 #continueWith(Continuation)
。 onSuccess
的 Continuation
只会在源任务成功解析时调用。如果将其更改为 continueWith
,则当源任务解析为成功、失败或取消时将调用 Continuation
。
我在理解有关 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;
}
}
假设我的代码中使用了上面的class,那么调用就是:
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() 方法,因为没有定义完成源。 如果我在自己的 classes 中有复杂的对象,我该如何正确使用这个框架?
另一种选择是完全避免 TaskCompletionSource 对象和 return 某种自定义任务状态对象,该对象将包含任务结果以及自定义 isError 和 Exception 属性。但这并不像使用 TaskCompletionSource 那样优雅。
您遇到的问题似乎是您使用的是 #onSuccess(Continuation)
而不是 #continueWith(Continuation)
。 onSuccess
的 Continuation
只会在源任务成功解析时调用。如果将其更改为 continueWith
,则当源任务解析为成功、失败或取消时将调用 Continuation
。