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
相关产品推荐
相关产品推荐

