使用协程在AccountManager中实现getAuthToken

问题描述 投票:0回答:1

我在实现getAuthToken时遇到问题。

   override fun getAuthToken(
        response: AccountAuthenticatorResponse,
        account: Account,
        authTokenType: String,
        options: Bundle
    ): Bundle? {
        val password = AccountManager.get(context).getPassword(account)
        val scope = CoroutineScope(Dispatchers.IO + Job())
        scope.launch {
            val user = getNetworkService().login(account.name, password)
            val token = Gson().toJson(user)
            // ERROR: return is not allowed here
            return Bundle().apply {
                putString(AccountManager.KEY_ACCOUNT_NAME, account.name)
                putString(AccountManager.KEY_ACCOUNT_TYPE, account.type)
                putString(AccountManager.KEY_AUTHTOKEN, token)
                Timber.i("Got auth token and bundle is $this")
            }
        }
    }

启动协同程序作用域时,无法返回网络调用后获得的令牌。错误,“此处不允许返回”。如何正确返回authToken?

android kotlin kotlin-coroutines
1个回答
0
投票

我想出的解决方案是在getAuthToken外部执行异步登录请求。

getAuthToken中,我要做的就是获取现有令牌,否则返回null

    // This method runs whenever the authToken is invalid or null
    // The first time it runs is after you add an account to accountManager
    // Use this method to fetch the token from the network/server and return it in a bundle
    // Do not call accountManager.setAuthToken(token) directly in the application
    override fun getAuthToken(
        response: AccountAuthenticatorResponse,
        account: Account,
        authTokenType: String,
        options: Bundle
    ): Bundle? {
        val authToken: String? = AccountManager.get(context).peekAuthToken(account, accountType)
        return authToken?.let { token ->
            Bundle().apply {
                putString(AccountManager.KEY_ACCOUNT_NAME, account.name)
                putString(AccountManager.KEY_ACCOUNT_TYPE, account.type)
                putString(AccountManager.KEY_AUTHTOKEN, token)
                Timber.i("Got auth token, bundle is $this")
            }
        }
    }

我不得不忽略方法上方的所有评论。

然后我直接从注册和登录片段中设置authToken

这是添加帐户的扩展功能。

fun Fragment.addAccount(email: String, password: String, token: String) {
    val am = AccountManager.get(activity)
    val account = Account(email, getAccountType())
    am.addAccountExplicitly(account, password, null)
    am.setAuthToken(account, accountType, token)
    am.setUserData(account, userData, token)
}
© www.soinside.com 2019 - 2024. All rights reserved.