解决ReactNative崩溃:Can't find variable: __fbBatchedBridge
来源:互联网 发布:零基础学sql视频教程 编辑:程序博客网 时间:2024/05/22 10:58
这个坑我花了两天时间才爬出来!!
首先关于这个问题,甭管google、百度还是看issue,大都给的解决方案是
+ 检查packager是否启动了?
+ 尝试adb reverse tcp:8081 tcp:8081
+ 打开dev模式,设置ip:8081(localhost:8081)
通过以上途径,如果解决了这个问题,恭喜你!那么这种情况下通常会紧跟一个——但是!
但是!我尝试了网上的所有方法都没办法解决我的问题,而且发现某个犄角旮旯里有个哥们也碰到和我一样的病症,但那哥们没有给出解决方案,只是说如果手动运行react bundle命令将js打包成bundle并放到项目的asserts目录下就可以正常运行。react bunlde命令其实是react.gradle的核心,我也尝试手工执行该命令打包bundle,发现确实可以正常运行。
那么问题来了!这个命令是在哪个task执行的?查看gradle面板,是在bundleDebugJsAndAssets/bundleReleaseJsAndAssets中执行,好,那么下面编译下看这个命令的执行结果。什么?竟然是bundleReleaseJsAndAssets SKIPPED。
在初始化的react-native的build.gradle的注释中有句这样的话:
“By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the bundle directly from the development server”
意思是在debug的编译模式下bundleDebugJsAndAssets会默认被skipped,但为什么我执行项目的assembleDebug执行的却是bundleReleaseJsAndAssets而不是bundleDebugJsAndAssets,而且竟然被skipped了?
当时我有两个完全靠第六感的猜测。(有时候第六感对于码农来说也蛮重要的)
第一个猜测是,58项目的application module名字为‘58WuxianClient’,会不会和数字开头有关?不过,我把module名称改为’WubaWuxianClient’后还是不行。第一个猜测失败。
第二个猜测,通过react-native init编译的初始化项目,RN Activity都是在application module中,而在我上一篇文章《如何将RN整合到58NA的Android项目中》描述,我创建了一个名为WubaRNLib的library module,现在启动的RN Activity都在这个module中,会不会和application/module有关系?然后我把WubaRNTestActivity(继承自ReactActivity)从library移动到application的module中。启动,竟然加载成功了!!
OK!那么接下来的矛盾重点就集中在library/application上了。
同样的代码在library和application中竟然两种执行结果,要解决这个问题只能深入到源码中查找答案。不过,这里我还不想讲RN解剖查看实现原理,只想了解ReactActivity的执行流程。好在RN提供了另一种页面实现方式,可以直接继承Activity,只需要实现DefaultHardwareBackBtnHandler接口即可。查看ReactActivity的代码,发现其实它就是这个套路。那么走起~
在WubaRNLib中新建Activity,核心代码如下:
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mRootView = new ReactRootView(this); mManager = ReactInstanceManager.builder() .setApplication(getApplication()) .setBundleAssetName("index.android.bundle") .setJSMainModuleName("index.android") .addPackage(new MainReactPackage()) .setUseDeveloperSupport(BuildConfig.DEBUG) .setInitialLifecycleState(LifecycleState.RESUMED) .build(); mRootView.startReactApplication(mManager,"WubaRNProV2",null); setContentView(mRootView);}
不出所料,启动这个Activity依然报java.lang.RuntimeException: ReferenceError: Can’t find variable: __fbBatchedBridge并crash,然后挪到application module下,启动,通过。这起码说明代码是没问题的。
在自己创建ReactInstanceManager时需要调用setBundleAssetName和setJSMainModuleName两个方法,这引起了我的注意。还记得上面说到,手动执行react bundle命令将js文件打包成bundle并放到assets下就可以正常运行么?
第六感,没错,还是第六感告诉我,library/application的矛盾解决点很可能和ReactInstanceManager有关系。那么,撸起袖子开始做实验吧。
我分别将这个Activity放到library/application中执行并debug,记录下ReactInstanceManager中的变量来做对比。发现setBundleAssetName和setJSMainModuleName方法设置的值一样,我又猜错了。但是!!(粗体)里面竟然有个mDevSupportManager不太一样。然后深入到源码中发现这个变量和setUseDeveloperSupport()有关。这个方法我传递的值是BuildConfig.DEBUG,因为编译时执行的是gradle assembleDebug,所以可以肯定的是application module编译时BuildConfig.DEBUG为true,但library module呢?
查看library中BuildConfig代码
public static final boolean DEBUG = Boolean.parseBoolean("true");
看上去也是true,没问题啊。算了!不管这么多了,直接把library module中的Activity中调用setUseDeveloperSupport的值改为true试试。结果,竟然执行通过了!看来找到了元凶。也就是说,虽然执行的是assembleDebug,但library module中BuildConfig.DEBUG其实是false。google后发现library在编译aar过程中其实执行的是release模式。这也印证了上面说的为什么执行的是bundleReleaseJsAndAssets而不是bundleDebugJsAndAssets。那么理论上修改gradle将libray module编译模式改成debug应该能解决这个问题。说干就干。
WubaRNLib.gradle
android { publishNonDefault true}
依赖WubaRNLib的module
dependencies { releaseCompile project(path: ':WubaRNLib', configuration: 'release') debugCompile project(path: ':WubaRNLib', configuration: 'debug')}
编译,运行,通过!
总结下,解决这个问题主要是用最传统也往往最能解决问题的二分大法,再加上一些直觉。
- 解决ReactNative崩溃:Can't find variable: __fbBatchedBridge
- ReactNative报错:Can't find variable: __fbBatchedBridge
- react-native 解决 Can't find variable: __fbBatchedBridge
- JSExecutionException: ReferenceError: Can't find variable: __fbBatchedBridge
- javascript--- Can't find variable: $
- react Can’t find variable
- 关于react-native遇到Can't find variable: TouchableHighlight
- can't find class: org.wltea.expression.datameta.Variable
- 解决 can't find referenced pointcut
- 解决can't find -lGL的问题
- 解决can't find -lGL的问题
- Error: Can't find Python executable "python", you can set the PYTHON env variable.解决办法
- Ionic 2, Using Angular 2 Pipe breaks on iOS—“Can't find variable: Intl”
- axios 在单元测试中遇到 can't find variable: promise 解决方法
- can‘t find lmysqlclient
- 解决 SyntaxHighlighter 出现 can't find brush for ... 的问题
- Spring:can't find referenced pointcut错误解决
- MissingResourceException: Can't find resource for bundle java....错误解决
- 第三周项目四-穷举法解决组合问题
- 在inet下写一个“HelloWorld”程序
- Android Studio添加Parcelable序列化小工具(快速提高开发效率)
- 工厂模式
- 【Android进阶】Android自定义组件之自动换行View,以TextView为例
- 解决ReactNative崩溃:Can't find variable: __fbBatchedBridge
- 【bzoj 3809】Gty的二逼妹子序列 题解&代码(c++)
- HTTP 错误 500.21 - Internal Server Error 解决方案
- 第3周项目3—输出星号图(打印菱形)
- static 关键字的作用
- 日期匹配星座,月日匹配星座,android 星座
- 第二周 项目四
- 第三周项目1
- jBPM--GPD中文乱码问题