You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从React Native文件与Kotlin类访问ReactContextBaseJavaModule

解决React Native原生Android类访问SharedPreferences模块的方案

最优方案:抽离SharedPreferences核心逻辑为独立工具类

把原来封装在ReactContextBaseJavaModule里的SharedPreferences操作逻辑,抽成一个独立的Android工具类,让RN模块和原生Android类共享这个工具类——这是最干净、低耦合的方案,完全避开RN模块的桥接限制。

实现步骤:

  1. 创建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)
        }
    }
    
  2. 改造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());
            }
        }
    }
    
  3. 原生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桥接用的异步方法)。

实现步骤:

  1. 在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);
        }
    }
    
  2. 在原生类中获取模块实例

    • 如果原生类在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")
      }
      

针对你遇到的挑战的具体解决办法:

  1. 无法传递ReactApplicationContext:用Application Context初始化工具类(工具类会自动用context.applicationContext避免内存泄漏),或者通过Application类/静态弱引用保存RN上下文。
  2. 无法访问@ReactMethod方法:不要直接调用@ReactMethod,在模块中编写同步的public方法供原生调用,@ReactMethod内部复用这些方法。
  3. 无法注入原生实例到RN模块:工具类方案不需要注入,模块直接依赖工具类;如果需要原生实例,可以在模块初始化时从Application类获取。

内容的提问来源于stack exchange,提问作者Maitrey C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 04:30:42