如何从React Native文件与Kotlin类访问ReactContextBaseJavaModule
最优方案:抽离SharedPreferences核心逻辑为独立工具类
把原来封装在ReactContextBaseJavaModule里的SharedPreferences操作逻辑,抽成一个独立的Android工具类,让RN模块和原生Android类共享这个工具类——这是最干净、低耦合的方案,完全避开RN模块的桥接限制。
实现步骤:
创建SharedPreferences工具类
用单例模式实现一个依赖Context的工具类,封装所有SharedPreferences的读写操作。示例Kotlin代码:class SharedPrefsHelper private constructor(private val context: Context) { companion object { private const val PREF_NAME = "MyAppPreferences" @Volatile private var INSTANCE: SharedPrefsHelper? = null fun getInstance(context: Context): SharedPrefsHelper { return INSTANCE ?: synchronized(this) { INSTANCE ?: SharedPrefsHelper(context.applicationContext).also { INSTANCE = it } } } } private val sharedPrefs: SharedPreferences by lazy { context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) } // 封装常用操作 fun putString(key: String, value: String) { sharedPrefs.edit().putString(key, value).apply() } fun getString(key: String, defaultValue: String? = null): String? { return sharedPrefs.getString(key, defaultValue) } fun putInt(key: String, value: Int) { sharedPrefs.edit().putInt(key, value).apply() } fun getInt(key: String, defaultValue: Int = 0): Int { return sharedPrefs.getInt(key, defaultValue) } }改造RN模块依赖工具类
原来的ReactContextBaseJavaModule不再直接操作SharedPreferences,而是调用工具类的方法。示例Java代码:public class SharedPrefsModule extends ReactContextBaseJavaModule { private final SharedPrefsHelper prefsHelper; public SharedPrefsModule(ReactApplicationContext reactContext) { super(reactContext); this.prefsHelper = SharedPrefsHelper.getInstance(reactContext); } @Override public String getName() { return "SharedPrefsModule"; } @ReactMethod public void putString(String key, String value, Promise promise) { try { prefsHelper.putString(key, value); promise.resolve(true); } catch (Exception e) { promise.reject("WRITE_ERROR", e.getMessage()); } } @ReactMethod public void getString(String key, String defaultValue, Promise promise) { try { String value = prefsHelper.getString(key, defaultValue); promise.resolve(value); } catch (Exception e) { promise.reject("READ_ERROR", e.getMessage()); } } }原生Android类直接调用工具类
任何原生类(Activity、Service、普通类)只要能拿到Context,就能获取工具类实例并读写SharedPreferences:// 在Activity中 val prefsHelper = SharedPrefsHelper.getInstance(this) val userToken = prefsHelper.getString("user_token") prefsHelper.putInt("login_count", 5)
备选方案:直接访问RN模块实例(不推荐,耦合性高)
如果不想重构代码,可以通过React Native的上下文获取RN模块实例,调用模块里暴露的原生方法(注意不要直接调用@ReactMethod注解的方法,这些是给JS桥接用的异步方法)。
实现步骤:
在RN模块中添加原生可调用的public方法
在SharedPrefsModule里添加同步的public方法,供原生类直接调用:public class SharedPrefsModule extends ReactContextBaseJavaModule { // ... 原有代码 ... // 暴露给原生Android类的同步方法 public String getNativeString(String key) { return prefsHelper.getString(key); } public void putNativeString(String key, String value) { prefsHelper.putString(key, value); } }在原生类中获取模块实例
- 如果原生类在RN上下文内(比如
ReactActivity):val reactContext = reactInstanceManager.currentReactContext as ReactApplicationContext val sharedPrefsModule = reactContext.getNativeModule(SharedPrefsModule::class.java) val userName = sharedPrefsModule.getNativeString("user_name") - 如果原生类不在RN上下文内(比如普通Service):
可以在Application类中保存ReactApplicationContext的弱引用(避免内存泄漏),或者在RN模块初始化时把自身实例保存到静态弱引用:
然后原生类中直接调用:public class SharedPrefsModule extends ReactContextBaseJavaModule { private static WeakReference<SharedPrefsModule> instanceRef; public SharedPrefsModule(ReactApplicationContext reactContext) { super(reactContext); instanceRef = new WeakReference<>(this); this.prefsHelper = SharedPrefsHelper.getInstance(reactContext); } // 提供静态方法获取实例 public static SharedPrefsModule getInstance() { return instanceRef != null ? instanceRef.get() : null; } // ... 原有代码 ... }val sharedPrefsModule = SharedPrefsModule.getInstance() sharedPrefsModule?.let { val userToken = it.getNativeString("user_token") }
- 如果原生类在RN上下文内(比如
针对你遇到的挑战的具体解决办法:
- 无法传递ReactApplicationContext:用Application Context初始化工具类(工具类会自动用
context.applicationContext避免内存泄漏),或者通过Application类/静态弱引用保存RN上下文。 - 无法访问@ReactMethod方法:不要直接调用
@ReactMethod,在模块中编写同步的public方法供原生调用,@ReactMethod内部复用这些方法。 - 无法注入原生实例到RN模块:工具类方案不需要注入,模块直接依赖工具类;如果需要原生实例,可以在模块初始化时从Application类获取。
内容的提问来源于stack exchange,提问作者Maitrey C
相关产品推荐
相关产品推荐

