使用flutter_inappbrowser 1.2.1二次打开浏览器报ChromeSafariBrowser已打开错误求助
我看到你遇到了这个头疼的问题:首次调用flutter_inappbrowser的ChromeSafariBrowser打开链接一切正常,但再次点击打开时就抛出了Cannot open ... ! The browser is already opened.的错误。这是因为你当前用的是全局单例的ChromeSafariBrowser实例,第一次打开后这个实例处于活跃状态,再次调用open方法时,库会检测到实例已打开,从而抛出冲突错误。
下面给你几个可行的解决方案,你可以根据自己的需求选:
方案1:每次点击时创建新的浏览器实例
最简单直接的解决方式就是去掉全局的chromeSafariBrowser变量,在用户点击"Read More..."时,直接创建一个新的MyChromeSafariBrowser实例并调用open方法。这样每次打开都是独立的实例,完全不会有"已打开"的冲突:
Center( child: InkWell( onTap: () { // 每次点击都创建新的浏览器实例 final chromeSafariBrowser = MyChromeSafariBrowser(inAppBrowserFallback); chromeSafariBrowser.open( url, options: { "addShareButton": true, "toolbarBackgroundColor": "#FFFFFF", "dismissButtonStyle": 1, "preferredBarTintColor": "#FFFFFF", "instantAppsEnabled": false }, optionsFallback: { "toolbarTopBackgroundColor": "#FFFFFF", "closeButtonCaption": "Close" } ); }, child: Text( 'Read More...', style: TextStyle( color: Color(0xFF38969A), fontSize: 16.0, decoration: TextDecoration.underline, fontWeight: FontWeight.bold), ), ) )
方案2:在浏览器关闭时重新初始化实例
如果你需要保留全局实例的方式,可以在MyChromeSafariBrowser的onClosed回调里重新初始化这个全局实例,这样每次关闭后,下次点击使用的就是全新的实例:
首先修改全局变量的声明,让它可以被重新赋值:
MyChromeSafariBrowser? chromeSafariBrowser; // 初始化方法 void _initBrowser() { chromeSafariBrowser = MyChromeSafariBrowser(inAppBrowserFallback); } // 在页面初始化时调用一次 @override void initState() { super.initState(); _initBrowser(); }
然后修改MyChromeSafariBrowser的onClosed方法:
class MyChromeSafariBrowser extends ChromeSafariBrowser { MyChromeSafariBrowser(browserFallback) : super(browserFallback); @override void onOpened() { print("ChromeSafari browser opened"); } @override void onLoaded() { print("ChromeSafari browser loaded"); } @override void onClosed() { print("ChromeSafari browser closed"); // 重新初始化实例,为下次打开做准备 chromeSafariBrowser = MyChromeSafariBrowser(inAppBrowserFallback); } }
最后在点击回调里直接调用即可:
onTap: () { chromeSafariBrowser?.open( url, options: { "addShareButton": true, "toolbarBackgroundColor": "#FFFFFF", "dismissButtonStyle": 1, "preferredBarTintColor": "#FFFFFF", "instantAppsEnabled": false }, optionsFallback: { "toolbarTopBackgroundColor": "#FFFFFF", "closeButtonCaption": "Close" } ); }
方案3:打开前检查状态并关闭已有实例
如果你的业务场景允许在打开新链接前关闭当前的浏览器窗口,可以在点击时先检查实例是否处于打开状态,若已打开则先关闭再打开新链接:
onTap: () async { // 检查浏览器是否已打开,若已打开则先关闭 if (chromeSafariBrowser?.isOpened ?? false) { await chromeSafariBrowser?.close(); } chromeSafariBrowser?.open( url, options: { "addShareButton": true, "toolbarBackgroundColor": "#FFFFFF", "dismissButtonStyle": 1, "preferredBarTintColor": "#FFFFFF", "instantAppsEnabled": false }, optionsFallback: { "toolbarTopBackgroundColor": "#FFFFFF", "closeButtonCaption": "Close" } ); }
注意:这个方案依赖库提供的isOpened属性和close方法,确保你的flutter_inappbrowser 1.2.1版本支持这些API。
以上几种方案都能解决你遇到的重复打开报错问题,其中方案1最直接简单,推荐优先尝试。
内容的提问来源于stack exchange,提问作者Sachin Varma

