android开发技巧React Native

React Native集成到Android现有项目(少走坑)

2020-03-13  本文已影响0人  Sky_Blue
一、中文参考官网

React Native集成到现有项目中文官网

二、在根目录cmd执行创建命令
  1. npm init (然后输入名称) 回车就好,生成package.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "yarn react-native start"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "16.9.0",
    "react-native": "0.61.3"
  }
}

  1. yarn add react@16.9.0(版本自己选择,在根目录cmd执行)
  2. yarn add react-native@0.61.5(版本自己选择,在根目录cmd执行)
  3. 在根目录新建android文件夹,打开AS创建新项目到这个文件夹(或者从git上clone下来到这里)
  4. Android项目ReactiNative配置及项目依赖
// 1. 项目setting.gradle配置(为了依赖三方库)
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'

// 2. 根目录build.gradle
allprojects {
    repositories {
        google()
        jcenter()
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }
        maven { url 'https://jitpack.io' }
    }
}

// 3. 项目依赖

// React Native依赖
implementation "com.facebook.react:react-native:+"
implementation 'org.webkit:android-jsc:+
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'

// 下面这几个是三方依赖库,不用管
implementation project(path: ':react-native-gesture-handler')
implementation project(path: ':react-native-screens')
implementation project(path: ':react-native-reanimated')
implementation project(path: ':react-native-safe-area-context')

  1. 编写JS,在根目录cmd执行打包命令,生成的index.android.bundle文件放到assets目录
    react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/


    bundle.png
三、建立React native Activity
/**
 * 创建ReactActivity
 */
public class MyReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mReactRootView = new RNGestureHandlerEnabledRootView(this);
        List<ReactPackage> packages =  new ArrayList<>(Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                // 下面这些是三方的,项目没有,就去掉
                new RNGestureHandlerPackage(),
                new ReanimatedPackage(),
                new SafeAreaContextPackage(),
                new RNScreensPackage(),
                // 下面这个地自己JS交互
                new RNPackage()
        ));

        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setCurrentActivity(this)
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackages(packages)
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        // 注意这里的MyReactNativeApp必须对应“index.js”中的
        // “AppRegistry.registerComponent()”的第一个参数
        Bundle build = new Bundle();
        build.putString("routeName", "Test");
        mReactRootView.startReactApplication(mReactInstanceManager, "carHouse", build);

        setContentView(mReactRootView);
    }

    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy(this);
        }
        if (mReactRootView != null) {
            mReactRootView.unmountReactApplication();
        }
    }

    @Override
    public void onBackPressed() {
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onBackPressed();
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
            mReactInstanceManager.showDevOptionsDialog();
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }
}

四、原生交互
  1. 定义与原生交互的类,继承ReactContextBaseJavaModule 类
/**
 * 与原生交互的类
 */
public class RNModule extends ReactContextBaseJavaModule {
    public RNModule(@NonNull ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @NonNull
    @Override
    public String getName() {
        // 名字可以任意,JS代码对应上即可
        return "RNModule";
    }

    /**
     * return 需要导出给JavaScript使用的常量。它并不一定需要实现,但在定义一些可以被JavaScript同步访问到的预定义的值时非常有用。
     */
    @Override
    public Map<String, Object> getConstants() {
        //让js那边能够使用这些常量
        Map<String, Object> constants = new HashMap<>();
        constants.put("baseURL", "https://***.cn");
        constants.put("token", "d5***ac5");
        constants.put("appVersion", "1.0.0");
        return constants;
    }

    /**
     * 自定义方法
     */
    @ReactMethod
    public void back() {
        Log.e("RNMerchantsManager", "RNMerchantsManager");
    }

    /**
     * 自定义带参数的方法
     */
    @ReactMethod
    public void back(String params) {
        Log.e("RNMerchantsManager", "RNMerchantsManager");
    }
}

  1. 定义注册类
/**
 * 注册
 */
public class RNPackage implements ReactPackage {
    @NonNull
    @Override
    public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new RNModule(reactContext));
        return modules;
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}
  1. 注入(在上面MyReactActivity里面)
 mReactInstanceManager = ReactInstanceManager.builder()
                // 自定义JS交互
                .addPackage(new RNPackage())         
                .build();

这里特别注意,别按官网那种写法,官网是在Application注入,不适用原生这种集成方式。

五、其它实在不行,就先用react-native init test 生成新的项目,看里面是怎么配置。
上一篇下一篇

猜你喜欢

热点阅读