一、核心概念和类概览
这三个类协同工作,共同管理和维护喜马拉雅账号的登录状态、用户信息,并处理与其他平台("Federation")的账号绑定。
XimalayaAccountProvider:
这是一个 Android ContentProvider 的实现。它的主要作用是作为跨进程通信的桥梁,允许其他应用或模块(特别是 XimalayaAccountManager)安全地访问和操作喜马拉雅账号数据和功能,而无需直接访问底层的 XimalayaAccountRepository。它通过 call() 方法暴露了一系列账号相关的操作,如获取用户信息、刷新 Token、登录、登出等。
XimalayaAccountRepository:
这是一个数据仓库(Repository)。它的核心职责是处理所有与喜马拉雅账号数据相关的业务逻辑。它不关心数据从哪里来(网络、缓存或本地数据库),只负责获取、处理和存储数据。它封装了与喜马拉雅开放平台 SDK 的交互,例如获取用户信息、检查登录状态、刷新 Token、执行登出操作等。它还负责将账号状态同步到另一个名为 "JDO" 的数据仓库,这可能是另一个平台或服务。
XimalayaFederationDelegate:
这是一个用于处理“联邦”(Federation)账号绑定的委托类。它实现了 ILoginDelegate 和 ILinkDelegate 接口,表明它能够处理登录和绑定相关的请求。这里的“联邦”指的是将喜马拉雅账号与另一个主账号系统(可能是汽车信息娱乐系统或其他平台)进行关联。该类负责在系统启动时尝试使用联邦 Token 自动登录,并处理来自主账号系统的绑定和解绑请求。
二、 登录流程(LoginDelegate 和 XimalayaAccountRepository)
登录流程分为几种情况,但核心都依赖 XimalayaAccountRepository 来执行实际的网络或本地操作。
通过 autoLoginWithFederation() 自动登录
检查联邦状态:
LoginDelegate的autoLoginWithFederation()方法在启动时被调用。它首先通过CommonDataHelper.getFederationInfo()获取联邦账号信息。验证联邦信息: 它检查获取到的联邦信息是否有效 (
isValid())、是否处于绑定状态 (federationStatus.toBoolean()),并且是否包含 Token。调用
loginWithFederationToken(): 如果联邦信息有效且包含 Token,它会调用XimalayaAccountManager的loginWithFederationToken(federationToken)方法。跨进程调用:
XimalayaAccountManager通过ContentResolver.call()调用XimalayaAccountProvider中的setFederationTokenAndLogin方法,并将联邦 Token 作为参数传递。XimalayaAccountRepository执行登录:XimalayaAccountProvider的call()方法接收到请求后,会调用accountRepository.autoLogin(arg),其中arg就是联邦 Token。刷新 Token:
XimalayaAccountRepository的autoLogin(refreshToken)方法首先将联邦 Token 保存为刷新 Token (accountStorage.saveRefreshToken(refreshToken)),然后调用dataRepository.refreshToken()去尝试获取新的访问 Token 和用户信息。更新状态: 如果
refreshToken()成功,XimalayaAccountRepository会调用updateOnlineUserInfo()和syncLoginStatus(true)来更新本地缓存、LiveData并同步登录状态到 JDO 平台。
通过 checkLoginResult() 登录(例如,二维码登录)
获取二维码 Token: 可能是通过
XimalayaAccountManager调用getQRCodeToken(),最终由XimalayaAccountRepository的getQRCodeToken()方法调用dataRepository.generateQrcode()。检查登录结果: 应用程序会周期性地调用
XimalayaAccountManager的checkLoginResult(token)方法,来查询用户是否已经通过扫描二维码登录。跨进程调用:
XimalayaAccountManager同样通过ContentResolver.call()调用XimalayaAccountProvider的checkLoginResult方法。XimalayaAccountRepository检查:XimalayaAccountProvider接收到请求后,调用accountRepository.checkLoginResult(it)。处理登录结果:
XimalayaAccountRepository调用dataRepository.checkLoginResult(qrcodeId)。根据返回的LoginResult,如果code是LOGIN_SUCCESS或WAIT_USERINFO,它会调用updateUserInfo()来更新状态,并在登录成功时调用syncLoginStatus(true)。
三、 登出流程
发起登出: 用户或系统(例如
LoginDelegate的onLogOutInvoked()方法)发起登出请求。LoginDelegate.onLogOutInvoked(): 这个方法是联邦系统的登出回调。它会通过ContentResolver.call()调用XimalayaAccountProvider的logout方法。XimalayaAccountProvider的logout: 该方法调用accountRepository.logout()。XimalayaAccountRepository执行登出:首先,它调用喜马拉雅 SDK 的
AccessTokenManager.getInstanse().loginOut()来执行 SDK 内部的登出逻辑。然后,它清除本地存储的 Token (
accountStorage.saveToken("", "", 0)) 和用户信息 (accountStorage.saveUserInfo(null))。最后,它更新
LiveData(updateUserInfo()) 并调用syncLoginStatus(false)将登出状态同步到 JDO 平台。
四、 账号绑定/解绑流程
账号绑定和解绑由 LinkDelegate 处理。这个类实现了 ILinkDelegate 接口,用于响应来自联邦主账号系统的绑定/解绑请求。
绑定 (onLinkFederationInvoked)
收到绑定请求: 当联邦系统发起绑定请求时,
LinkDelegate的onLinkFederationInvoked()方法被调用,并传入主账号的puid和pvin。检查本地登录状态: 该方法首先检查本地喜马拉雅账号是否已登录 (
accountManager.getUserInfoValue() != null)。同步绑定状态: 如果已登录,它会调用
jdoDataRepository.uploadMediaAccountStatus()。这个方法是关键,它将喜马拉雅账号的登录状态和信息(refreshToken、nickname、avatar_url等)以及联邦系统的puid和pvin上传到 JDO 平台,从而完成账号的逻辑绑定。返回结果: 根据
uploadMediaAccountStatus()的结果,返回ResponseBean.SUCCESS或ResponseBean.obtainFailure()。
解绑(onUnlinkFederationInvoked)
收到解绑请求: 当联邦系统发起解绑请求时,
LinkDelegate的onUnlinkFederationInvoked()方法被调用。同步解绑状态: 它调用
jdoDataRepository.uploadMediaAccountStatus(),但这次将federationStatus参数设为0,token和refreshToken设为null,以通知 JDO 平台喜马拉雅账号与主账号的绑定关系已被解除。返回结果: 根据
uploadMediaAccountStatus()的结果,返回ResponseBean.SUCCESS或ResponseBean.obtainFailure()。
五、类的相互作用总结
XimalayaAccountRepository:
负责业务逻辑和数据源(网络 API、本地存储)的交互。它不直接与 UI 或其他进程通信,而是通过 LiveData 或返回数据对象的方式。
XimalayaAccountProvider:
负责跨进程通信。它将 XimalayaAccountRepository 的功能以 ContentProvider 的形式暴露出去,使得其他应用或模块可以通过 ContentResolver.call() 远程调用这些功能。
XimalayaAccountManager:
作为一个客户端类,它封装了对 XimalayaAccountProvider 的 ContentResolver.call() 调用,提供了更友好的 Kotlin suspend 函数接口,供上层业务逻辑(如 LoginDelegate)调用。它也负责通过 ContentObserver 监听 XimalayaAccountProvider 的数据变化。
XimalayaFederationDelegate:
负责特定场景(联邦绑定)的业务逻辑。它依赖 XimalayaAccountManager 来执行具体的登录、登出和状态同步操作,并实现联邦系统所需的特定接口。