gpt4 book ai didi

java - 在 AsyncTask 中使用 ListenableFuture Azure 调用

转载 作者:行者123 更新时间:2023-11-29 20:30:48 25 4
gpt4 key购买 nike

我对 Android、Java 和 Azure 有点陌生,我正在使用 Azure MobileServiceClient 类尝试调用后端中的各种 API。我遇到的问题是 MobileServiceClient 的方法似乎都是异步的,使用 ListenableFutures。

这很好,只是我想在辅助类中使用这些方法,该类还执行其他应该异步的操作(因此它扩展了 AsyncTask)。但是,由于 MobileServiceClient 调用是异步的,因此会导致 AsyncTask 过早返回。我希望 AsyncTask 在 MobileServiceClient 方法返回之前不要调用其 onPostExecute 方法。

如何避免这个问题?我需要改变我的架构吗?是否可以将 MobileServiceClient 调用放入另一个异步任务中并让它阻止它?

@Override
protected Boolean doInBackground(Void... params) {
Log.i(TAG, "Doing background task");
if(mTaskType==tTaskType.LOGIN_TASK){
login();
//do other stuff here that should be async
}
return true;
}

private void login(){
Log.i(TAG, "Doing login task...");
ListenableFuture<JsonElement> result = mClient.invokeApi("login", mJSONHelper.makeLoginObject(thisUser));
Futures.addCallback(result, new FutureCallback<JsonElement>() {
@Override
public void onFailure(Throwable exc) {
error.setError(ErrorHelper.Error.NETWORK_ERROR);
}

@Override
public void onSuccess(JsonElement result) {

}
});
}

最佳答案

在此之前,我要声明一下,我对 Android 也不是很熟悉。然而,根据我在其他平台上的经验以及对 API 的快速搜索,我认为这是您应该采取的方法。我也不 promise 代码 fragment 会编译,因为我还没有检查过,但它们应该接近这样做。

您的login方法应该返回 ListenableFuture<T>然后是 doInBackground然后方法可以添加它自己的回调,该回调在登录完成时执行。

如果你想要别的东西可以等待doInBackground然后完成任务,还应该返回 ListenableFuture<T>这可以通过使用 Futures.transform 来完成将一系列异步调用链接在一起的方法。

我认为它应该是这样的:

protected void doInBackground(Void... params) {
Log.i(TAG, "Doing background task");
if(mTaskType==tTaskType.LOGIN_TASK){
var loginFuture = ListenableFuture<UserDetail> login();

Futures.addCallback(loginFuture, new FutureCallback<UserDetail>() {
@Override
public void onSuccess(UserDetail userDetail)
{
// do other stuff here that should be async
// also optionally you could implement this as a transform
// style thing to and return another future from this `doInBackground`
// method so other parts of your code could know when it is completed.
}

@Override
public void onFailure(Throwable exc) {
// I'd quite likely move the error handling from the login method here
// as that way it can also handle any exceptions caused by the transform
// from json to user detail as well.
}
})
}
}

private ListenableFuture<UserDetail> login(){
Log.i(TAG, "Doing login task...");
ListenableFuture<JsonElement> loginFutureResult = mClient.invokeApi("login", mJSONHelper.makeLoginObject(thisUser));
Futures.addCallback(loginFutureResult, new FutureCallback<JsonElement>() {
@Override
public void onFailure(Throwable exc) {
// This is just to keep with what your style is, for recording the error
// I think you might be better off handling it at a higher level and
// also you might want to check `exc` to see if it was an actual network
// error and not for example just failed credentials or something.
error.setError(ErrorHelper.Error.NETWORK_ERROR);
}

@Override
public void onSuccess(JsonElement result) {
Log.i(TAG, "The login was successful");
}
});

// lets pretend that instead of returning the JSON response
// you wanted to map it to a user detail before returning, just to show how to do that.

AsyncFunction<JsonElement, UserDetail> transformUserJsonFunction =
new AsyncFunction<JsonElement, UserDetail>() {
public ListenableFuture<UserDetail> apply(JsonElement userJson) {
// some code to map the json element to user detail
UserDetail userDetail = new UserDetail(userJson);
return Futures.immediateFuture(userDetail);
}
};


return Futures.transform(loginFutureResult, transformUserJsonFunction);
}

我希望这能为您指明正确的方向。

关于java - 在 AsyncTask 中使用 ListenableFuture Azure 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32024020/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com