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

如何在Expo原生模块中创建新的ReactRootView?

在Expo原生模块中渲染React Native组件到悬浮窗的解决方案

一、添加必要的原生依赖

在你的Expo原生模块的模块级build.gradle文件中,添加以下依赖,确保能获取React Native核心组件和react-native-paper的原生支持:

dependencies {
    // React Native核心库(版本需与你的Expo项目RN版本匹配)
    implementation "com.facebook.react:react-native:+"
    // react-native-paper的原生依赖
    implementation project(':react-native-paper')
    // Expo模块核心依赖(确保已存在)
    implementation project(':expo-modules-core')
}

二、通过Expo的ReactNativeHost获取ReactInstanceManager

Expo环境下不能直接实例化ReactRootView,需要借助Expo提供的ReactActivityProvider接口获取ReactInstanceManager,再创建并挂载你的JS组件。以下是悬浮窗服务的核心代码示例:

import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import expo.modules.core.interfaces.ReactActivityProvider;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.view.WindowManager;

public class FloatingChipService extends Service {
    private ReactRootView mReactRootView;
    private WindowManager mWindowManager;

    @Override
    public void onCreate() {
        super.onCreate();

        // 从Expo应用上下文获取ReactInstanceManager
        ReactInstanceManager reactInstanceManager = 
            ((ReactActivityProvider) getApplicationContext()).getReactNativeHost().getReactInstanceManager();

        // 初始化ReactRootView并启动注册好的MyChip组件
        mReactRootView = new ReactRootView(this);
        mReactRootView.startReactApplication(
            reactInstanceManager,
            "MyChip", // 对应JS端AppRegistry.registerComponent的组件名
            null // 传递给组件的props,可根据需求传入
        );

        // 配置悬浮窗布局参数
        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            android.graphics.PixelFormat.TRANSLUCENT
        );

        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(mReactRootView, layoutParams);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mReactRootView != null) {
            mWindowManager.removeView(mReactRootView);
            mReactRootView.unmountReactApplication();
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

三、确保JS组件正确注册

JS端的MyChip组件需通过AppRegistry.registerComponent完成注册,确保Android端能找到对应的组件:

import React from 'react';
import { AppRegistry } from 'react-native';
import { Chip } from 'react-native-paper';

const MyChip = () => {
  return (
    <Chip 
      icon="bell" 
      onPress={() => {/* 处理点击逻辑 */}}
      style={{ backgroundColor: '#fff' }}
    >
      后台悬浮Chip
    </Chip>
  );
};

// 注册组件,名称需与Android端startReactApplication传入的一致
AppRegistry.registerComponent('MyChip', () => MyChip);

export default MyChip;

四、关键注意事项

  • 悬浮窗权限:在AndroidManifest.xml中声明<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />,并在运行时引导用户开启权限。
  • 前台服务配置:确保你的服务已配置为前台服务,避免被系统回收。
  • 版本一致性:确保原生模块依赖的React Native版本与你的Expo项目版本完全匹配,避免依赖冲突。
  • 组件卸载:在服务销毁时务必移除ReactRootView并调用unmountReactApplication,防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:07:38