我目前正在尝试处理演示应用程序中的情况我写的是我有一个过期的访问令牌,我需要使用刷新令牌来获取新的访问令牌。对于像这样的后台任务,我通常使用像我的应用程序当前用于登录的AsyncTask(工作正常),但我不知道如何做到这一点 - 如果它甚至可以完成(I&I) “我相信它可以,但我现在还没有看到它。”
以下是我当前的流程 - 对 get()的调用阻止了UI线程,这不是我应该在这里做的事情。我们的访问权限类包含访问令牌和刷新令牌。
public boolean isLoggedIn() {
if (isFreshAccessToken())
return true;
// If the access token is expired, we'll need to use the
// refresh token to get another one. Use a background task
// to do this.
String refreshToken = preferences.getString(REFRESH_TOKEN_KEY, null);
if (StringUtils.isNotBlank(refreshToken)) {
RefreshAccessTokenAsyncTask refreshLogin = new RefreshAccessTokenAsyncTask();
refreshLogin.execute(refreshToken);
try {
return refreshLogin.get();
} catch (Exception e) {
Log.d(TAG, "isLoggedIn() : Exception in async task. Returning false.");
return false;
}
} else
return false;
}
这是我的AsyncTask实现目前的样子。 refreshAccessTicket()方法只是进行REST调用以获取AccessTicket响应。
private class RefreshAccessTokenAsyncTask extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
String refreshToken = params[0];
try {
// Get a new access token using the refresh token
// in the background ...
AccessTicket accessTicket = refreshAccessTicket(refreshToken);
// ... and save the updated information to the shared
// preferences
saveAccessTicket(accessTicket);
return true;
} catch (Exception ex) {
// If the call for a new access token fails for any reason,
// return FALSE. We'll force the user to log in again to
// get a completely new access ticket.
return false;
}
}
@Override
protected void onPostExecute(Boolean isLoggedIn) {
super.onPostExecute(isLoggedIn);
Log.d(TAG, "RefreshAccessTokenAsyncTask.onPostExecute() : " +
"Returning isLoggedIn value of " + isLoggedIn);
}
}
我在这里缺少什么?正如我上面提到的,我希望这个过程是静默的 - 如果访问令牌已经过期,我想使用刷新令牌自动获取新的访问令牌,而无需用户做任何事情或让应用跳出来当前流程(例如获取朋友列表等) - 它将在后台发生。我应该使用AsyncTask以外的东西吗?
答案 0 :(得分:1)
AsyncTask应该可以正常工作,但你不能得到那样的结果。尝试这样的事情。
private interface Callback {
void done(boolean result);
}
private class RefreshAccessTokenAsyncTask extends AsyncTask<String, Void, Boolean> {
private Callback cb;
private RefreshAccessTokenAsyncTask(Callback callback)
cb = callback;
}
@Override
protected Boolean doInBackground(String... params) {
String refreshToken = params[0];
try {
// Get a new access token using the refresh token
// in the background ...
AccessTicket accessTicket = refreshAccessTicket(refreshToken);
// ... and save the updated information to the shared
// preferences
saveAccessTicket(accessTicket);
return true;
} catch (Exception ex) {
// If the call for a new access token fails for any reason,
// return FALSE. We'll force the user to log in again to
// get a completely new access ticket.
return false;
}
}
@Override
protected void onPostExecute(Boolean isLoggedIn) {
super.onPostExecute(isLoggedIn);
Log.d(TAG, "RefreshAccessTokenAsyncTask.onPostExecute() : " +
"Returning isLoggedIn value of " + isLoggedIn);
cb.done(isLoggedIn);
}
}
然后像这样使用AsyncTask:
public boolean isLoggedIn() {
if (isFreshAccessToken())
return true;
// If the access token is expired, we'll need to use the
// refresh token to get another one. Use a background task
// to do this.
String refreshToken = preferences.getString(REFRESH_TOKEN_KEY, null);
if (StringUtils.isNotBlank(refreshToken)) {
Callback callback = new Callback() {
public void done(boolean result){
// whatever you need to do here
}
}
RefreshAccessTokenAsyncTask refreshLogin = new RefreshAccessTokenAsyncTask(callback);
refreshLogin.execute(refreshToken);
} else
return false;
}