使用SyncAdapters登录时两次 [英] Login in twice when using SyncAdapters

查看:294
本文介绍了使用SyncAdapters登录时两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 SyncAdapter 来处理数据库同步创建一个新的Andr​​oid应用程序。 我把一切都到位,并应用程序工作正常,但我注意到,我登录两次。

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 using mAccountManager.addAccountExplicitly()
  • The authToken is saved using intent.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆