You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android模块化:跨模块登录成功后如何回调并重试失败API请求?

这确实是Android模块化开发里非常典型的痛点——用startActivityForResult处理大量未授权请求时,不仅代码冗余度高,分散的回调逻辑还容易让流程变得混乱。我分享几个实战中验证过的思路,帮你优雅地暂存并重试请求:

方案1:全局请求队列 + 事件总线(快速落地首选)

核心思路是把未授权的请求封装成可执行任务,统一放到全局队列里,登录成功后通过事件通知触发批量重试,彻底摆脱Activity回调的束缚。

  • 实现步骤:

    1. 定义PendingRequest数据类,保存请求的核心信息:比如API接口地址、请求参数、成功/失败回调(可以用Lambda或者自定义接口)、请求优先级等。
    2. 在Module A的网络拦截器(比如OkHttp Interceptor)里捕获401错误,把当前请求包装成PendingRequest,加入全局单例的PendingRequestQueue,然后启动Module B的登录Activity(注意加判断,避免重复启动登录页)。
    3. Module B登录成功后,通过事件总线(比如EventBus、RxBus,或者用Jetpack LiveData实现简易事件流)发送「登录成功」事件。
    4. 在全局监听类(比如Application类、或者专门的RequestRetryManager单例)里接收事件,遍历队列中的PendingRequest,依次执行请求,执行完成后从队列中移除。
  • 优势:

    • 集中管理所有未授权请求,不用在每个页面写onActivityResult逻辑;
    • 跨模块解耦,Module A和Module B只依赖事件总线,不用直接持有对方的Activity引用;
    • 可以轻松实现请求去重、优先级排序等扩展功能。
  • 注意事项:

    • 确保请求队列的线程安全,建议用ConcurrentLinkedQueue或者加锁处理;
    • 登录成功后要清空队列,避免重复重试。
方案2:Jetpack Lifecycle + 单例请求管理器(更安全的页面感知重试)

如果需要确保请求只在页面活跃时重试,避免页面销毁后触发回调导致的异常,可以结合Lifecycle来实现。

  • 实现步骤:

    1. 创建单例AuthRetryManager,提供addPendingRequest、onLoginSuccess方法,内部维护请求列表和页面的Lifecycle引用。
    2. 每个发起API请求的Fragment/Activity实现Retryable接口,包含retryRequest()方法,在页面创建时向AuthRetryManager注册自己的Lifecycle。
    3. 拦截到401时,把请求对应的Retryable实例和请求参数存入管理器,启动登录页。
    4. 登录成功后,AuthRetryManager遍历所有注册的Retryable实例,通过Lifecycle判断页面是否处于活跃状态(比如Lifecycle.State.RESUMED),如果活跃则调用retryRequest(),否则可以等待页面恢复活跃后自动重试。
  • 优势:

    • 结合Lifecycle自动感知页面生命周期,避免内存泄漏和无效回调;
    • 可以针对不同页面的状态灵活处理重试逻辑(比如后台页面不重试,回到前台再触发)。
方案3:Repository层封装 + 挂起函数(Coroutines技术栈最优解)

如果你的项目用了Kotlin Coroutines,把重试逻辑封装在Repository层是最优雅的方式,上层页面完全不用关心登录和重试的细节。

  • 实现步骤:

    1. 在全局的NetworkRepository里封装所有API请求方法,内部统一处理401错误。
    2. 当捕获到401时,先检查是否正在进行登录流程,如果没有则挂起当前Coroutine,启动登录Activity(可以用runBlocking或者把登录流程封装成挂起函数,确保Coroutine等待登录完成)。
    3. 登录成功后更新全局Token,然后重新执行原请求。
  • 示例代码(Coroutines版):

suspend fun <T> safeApiCall(block: suspend () -> T): T {
    return try {
        block()
    } catch (e: HttpException) {
        if (e.code() == 401) {
            // 挂起直到登录成功
            authManager.performLogin()
            // 重试原请求
            block()
        } else {
            throw e
        }
    }
}
  • 优势:
    • 上层页面调用API时只需一行代码,完全感知不到登录和重试逻辑;
    • 利用Coroutines的挂起特性,避免回调地狱,代码可读性极强;
    • 模块化彻底,登录逻辑和API请求逻辑完全解耦。
总结推荐
  • 如果项目已经在用事件总线,优先选方案1,快速落地且改动小;
  • 对页面生命周期敏感、需要避免无效重试的场景,选方案2;
  • 用Kotlin Coroutines的新项目,强烈推荐方案3,代码最简洁优雅。

内容的提问来源于stack exchange,提问作者OnDWay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 18:52:34