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

Android 12以下版本打开Custom Tab致调用Activity销毁的问题求助

解决方案:Android 12以下Custom Tab认证重定向避免Activity重建

核心问题分析

Android 12及以上系统对Custom Tab的任务栈处理逻辑做了优化,能正确触发singleTop模式Activity的onNewIntent();但12以下版本中,从Custom Tab重定向回应用时,系统会默认创建新的任务栈,导致原有CustomTabLoginActivity实例被销毁重建,丢失状态。而添加FLAG_ACTIVITY_NEW_TASK会让Custom Tab留在最近任务列表,违背其设计初衷。

可行解决方案

通过给Custom Tab配置定向复用当前Activity的PendingIntent,确保重定向时直接触发onNewIntent(),同时不破坏任务栈结构。

1. 保留原有Manifest配置

无需修改CustomTabLoginActivity的launchMode和intent-filter,保持如下配置即可:

<activity
    android:name="com.example.CustomTabLoginActivity"
    android:exported="true"
    android:launchMode="singleTop">

    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data android:scheme="myapp" />
        <data android:host="@string/host_url_authentication" />
        <data android:pathPattern="/auth/callback.*" />
    </intent-filter>

</activity>

2. 修改Custom Tab启动逻辑

在openCustomTab方法中,创建指定FLAG_ACTIVITY_SINGLE_TOP的PendingIntent,绑定到CustomTabsIntent,确保重定向时复用已有Activity实例:

private fun openCustomTab(languageCode: String, authSession: String) {
    val loginUrl = "www.myappauth.com/someauthurl"
    
    // 创建PendingIntent,确保重定向时复用singleTop的Activity
    val pendingIntent = PendingIntent.getActivity(
        this,
        0,
        Intent(this, CustomTabLoginActivity::class.java).apply {
            action = Intent.ACTION_VIEW
            flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
        },
        // 适配Android 12及以上的Mutable标记
        PendingIntent.FLAG_UPDATE_CURRENT or 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_MUTABLE else 0
    )

    val customTabsIntent = CustomTabsIntent.Builder()
        .setColorScheme(CustomTabsIntent.COLOR_SCHEME_LIGHT)
        // 设置PendingIntent配置,指定重定向时的启动规则
        .setPendingIntentConfig(CustomTabsIntent.PendingIntentConfig.Builder(pendingIntent).build())
        .build()
    
    customTabsIntent.launchUrl(this, Uri.parse(loginUrl))
}

3. 完善onNewIntent处理

在CustomTabLoginActivity中,务必在onNewIntent()中更新当前Intent并处理Token:

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    // 更新当前Intent,避免后续获取数据时拿到旧值
    setIntent(intent)
    // 处理重定向携带的Token逻辑
    intent?.data?.let { uri ->
        val token = uri.getQueryParameter("token")
        // 后续业务处理...
    }
}

原理说明

通过PendingIntent明确指定重定向时的Activity启动规则,强制系统复用当前任务栈中的singleTop实例,而非创建新任务栈或重建Activity。同时,该方式不会让Custom Tab单独留在最近任务列表,符合其"内嵌式浏览器"的设计初衷。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:05:16