使用SyncAdapters登录时两次 [英] Login in twice when using SyncAdapters
问题描述
我使用 SyncAdapter
来处理数据库同步创建一个新的Android应用程序。
我把一切都到位,并应用程序工作正常,但我注意到,我登录两次。
I am creating a new Android app using SyncAdapter
to handle db sync.
I have everything in place and the app is working fine but I noticed that I am logged in twice.
在第一次登录时发生的 AuthenticatorActivity
类(它扩展 AccountAuthenticatorActivity
)验证用户名和密码。
The first login takes place when the AuthenticatorActivity
class (it extends AccountAuthenticatorActivity
) validates the user and password.
如果用户名和密码是正确的 AuthenticatorActivity
然后执行:
If the user and password are correct the AuthenticatorActivity
then does:
- 如果在
帐户
不存在使用它创建它mAccountManager.addAccountExplicitly()
- 的
的authToken
使用保存intent.putExtra(AccountManager.KEY_AUTHTOKEN,的authToken);
- If the
account
didn't exist it creates it usingmAccountManager.addAccountExplicitly()
- The
authToken
is saved usingintent.putExtra(AccountManager.KEY_AUTHTOKEN, authToken);
这基本上复制/从Android样品粘贴的,所以我想这是好的。
This was basically copied/pasted from the Android samples, so I guess it's ok.
问题是,当 SyncAdapter
启动和使用
authtoken = mAccountManager.blockingGetAuthToken(account,
AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, true);
在 getAuthToken()
的身份验证
类,它扩展了内法 AbstractAccountAuthenticator
被调用。而这个方法中,我打在登录端点一次。
The getAuthToken()
method inside the Authenticator
class which extends AbstractAccountAuthenticator
is called. And inside this method I am hitting the login endpoint once again.
从该点起登录端点没有再次命中,直到的authToken
到期。
From that point onwards the login endpoint is not hit again until the authToken
expires.
这是不是困扰我了很多,但我想知道是否有一种方法来避免做登录两次。
This is not something that bothers me a lot but I would like to know if there is a way to avoid doing the login twice.
推荐答案
正如你所看到的,尽管 Authenticator.java
在SampleSyncAdapter说
As you've seen, though Authenticator.java
in the SampleSyncAdapter says
有趣的,这类演示是利用authTokens的作为认证过程的一部分。 ...如果我们已经有存储在帐户中的authToken,我们返回的authToken。如果我们不这样做,但我们有一个用户名和密码,然后我们将尝试去跟示例服务来取出的authToken。
The interesting thing that this class demonstrates is the use of authTokens as part of the authentication process. ... If we already have an authToken stored in the account, we return that authToken. If we don't, but we do have a username and password, then we'll attempt to talk to the sample service to fetch an authToken.
这是一个谎言。 Authenticator.getAuthToken
并没有任何高速缓存检查,它只是打网络获得的令牌。
that's a lie. Authenticator.getAuthToken
doesn't to any cache checking, it just hits the network to get a token.
的解决方案是在缺少检查添加:
The solution is to add in the missing check:
Authenticator.java:
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
String authTokenType, Bundle loginOptions) throws NetworkErrorException {
// check that authToken type supported
...
// Check if we already have a cached token to return
final AccountManager am = AccountManager.get(mContext);
String cachedAuthToken = am.peekAuthToken(account, authTokenType);
if (cachedAuthToken != null) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
result.putString(AccountManager.KEY_AUTHTOKEN, cachedAuthToken);
return result;
}
// Get new authToken from server
...
// If all else fails, prompt the user for credentials
...
}
请注意,您的项目的其余部分需要宗教使用 AccountManager.invalidateAuthToken
时,调用失败,否则你会风与呼叫失败的一个无限循环,尝试获得一个新的身份验证令牌,然后再次失败时,返回相同的缓存身份验证令牌。
Note that the rest of your project needs to religiously use AccountManager.invalidateAuthToken
when calls fail or else you'll wind up with an infinite loop of calls failing, trying to get a new auth token, and then failing again when the same cached auth token is returned.
这篇关于使用SyncAdapters登录时两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!