启动CustomTabs时发起Activity自动销毁、状态丢失如何解决?
问题原因&修复方案
- Manifest启动模式配置缺失
你当前的CustomTabActivity配置了BROWSABLE类的deeplink过滤器,但未指定启动模式,默认使用standard模式。当CustomTab完成流程跳转回你的应用deeplink时,系统会创建全新的CustomTabActivity实例,而非复用之前发起CustomTab的旧实例,旧实例会被系统直接回收销毁,自然不会触发onRestoreInstanceState回调,也无法拿到原有状态。
修复方案:在Manifest的
CustomTabActivity节点添加启动模式配置:android:launchMode="singleTask"配置后同一任务栈内只会保留一个
CustomTabActivity实例,deeplink回调时会直接复用后台已有的旧实例,通过onNewIntent方法传递新的Intent数据。
- onCreate未主动读取 savedInstanceState 状态
onRestoreInstanceState的执行时机晚于onCreate,你当前仅在onRestoreInstanceState中赋值caller,如果Activity被系统销毁后重建,onCreate里的else分支执行打印逻辑时,caller还未被赋值,会出现状态丢失的假象。部分系统场景下重建仅会在onCreate中传递savedInstanceState,不会触发onRestoreInstanceState,也会导致状态丢失。
修复方案:在
onCreate开头优先恢复保存的状态:@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 优先读取已保存的状态 if (savedInstanceState != null) { this.caller = savedInstanceState.getString("caller", null); } if (getIntent().getBooleanExtra("starting", false)) { this.caller = getIntent().getStringExtra("caller"); // 后续CustomTab启动逻辑 } else { System.out.println(this.caller); } }
- CustomTab启动方式冗余异常
你用PendingIntent包装CustomTab Intent再通过IntentSender启动的写法不符合官方规范,冗余的包装逻辑可能导致上下文关联异常,触发发起Activity被自动销毁。同时你给CustomTab Intent添加的FLAG_ACTIVITY_NO_HISTORY会导致CustomTab关闭时直接跳过回退流程,也是你的发起Activity被销毁的核心诱因。
修复方案:改用官方推荐的启动方式,删除不必要的flag:
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder() .setUrlBarHidingEnabled(true) .setShowTitle(false) .build(); if (hasChrome()) { customTabsIntent.intent.setPackage("com.android.chrome"); } // 直接用提前注册的ActivityResultLauncher启动即可 customTabLauncher.launch(customTabsIntent.intent);
- 新增deeplink回调处理逻辑
配置singleTask启动模式后,deeplink回调的Intent不会传入onCreate,需要重写onNewIntent方法接收回调数据:
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); // 此处处理CustomTab返回的deeplink数据,caller已经是之前保存的状态值 Uri callbackData = intent.getData(); // 后续业务逻辑处理 }
内容的提问来源于stack exchange,提问作者Rafael Lima
相关产品推荐
相关产品推荐

