在混合应用中,多个Activity
/ Fragment
实例嵌套自己的ReactRootView
共享一个ReactInstanceManager
实例,似乎没有正式方法可以注入每个Activity
/ Fragment
实例的本机模块。本质上,本机模块是单独的,例如驻留在.js
文件中的javascript模块。如果在同一Fragment
的不同实例中运行的JS代码想要访问Java / Kotlin端以与Fragment
的本地属性进行交互,则这不是预期的行为。
我尝试使用registerAdditionalPackages()
的{{1}}方法,但如果多个ReactInstanceManager
s / Fragment
同时使用,则会失败并出现如下所示的断言错误。
Activity
这不是线程安全问题,而是"Extending native modules with non-matching application contexts."
实现的设计结果。还有另一种方法,如果是这样,你如何访问JS方面注入的模块?
答案 0 :(得分:0)
这个问题使我几天保持清醒。最后,我有一个解决方案。我希望它能帮助将来的某个人。解决方案在Kotlin中,但将其转换为Java非常简单。 registerAdditionalPackages()
是一个“非空”断言,大写someVariable!!
调用是实例创建,SomeObject()
是继承或实现,SomeType:SomeOtherType
是变量声明。其余的都一样。
步骤:
1)在您希望将模块注入RN运行时时运行以下代码。 val someVar:SomeType
或Activity.onCreate()
内部是一些不错的候选人。 Fragment.onCreateView()
是您的单身全局反应运行时。 mReactInstanceManager
定义将在稍后给出。
packageToInject
2) synchronized(mReactInstanceManager!!.currentReactContext!!) {
val nativeModuleRegistryBuilder = NativeModuleRegistryBuilder(
mReactInstanceManager!!.currentReactContext as ReactApplicationContext?,
mReactInstanceManager!!,
false
)
nativeModuleRegistryBuilder.processPackage(packageToInject)
mReactInstanceManager!!.currentReactContext!!.catalystInstance!!.extendNativeModules(nativeModuleRegistryBuilder.build())
}
中的实例必须按照以下方式准备,以便为每个packageToInject
/ Fragment
实例创建一个唯一名称的唯一模块。制作Activity
或Fragment
。
Activity
3)当您在class ReactManagerPackage : ReactPackage {
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
}
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
val modules = ArrayList<NativeModule>()
modules.add(ReactBridge(reactContext))
return modules
}
}
class ReactBridge(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
override fun getName(): String {
return myFragmentOrActivity.hashCode().toString()
}
@ReactMethod
fun showToast(text: String) {
Toast.makeText(text, Toast.LENGTH_SHORT).show()
}
}
或myFragmentOrActivity.hashCode().toString()
中启动mReactRootView.startReactApplication()
时,将Activity.onCreate()
作为道具传递。把它放在你给Fragment.onCreateView()
作为第三个参数的包中。
mReactRootView.startReactApplication()
4)使用组件中的prop(本例中为val bundle = Bundle()
bundle.putString("fragmentOrActivityHash", myFragmentOrActivity.hashCode().toString())
mReactRootView.startReactApplication(mReactInstanceManager, "MyRootComponent", bundle )
)来检索特定的桥。 (JavaScript)的
MyRootComponent
利润!