React Native集成到Android现有项目(少走坑)
2020-03-13 本文已影响0人
Sky_Blue
一、中文参考官网
二、在根目录cmd执行创建命令
- 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"
}
}
- yarn add react@16.9.0(版本自己选择,在根目录cmd执行)
- yarn add react-native@0.61.5(版本自己选择,在根目录cmd执行)
- 在根目录新建android文件夹,打开AS创建新项目到这个文件夹(或者从git上clone下来到这里)
- 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')
-
编写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);
}
}
四、原生交互
- 定义与原生交互的类,继承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");
}
}
- 定义注册类
/**
* 注册
*/
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();
}
}
- 注入(在上面MyReactActivity里面)
mReactInstanceManager = ReactInstanceManager.builder()
// 自定义JS交互
.addPackage(new RNPackage())
.build();
这里特别注意,别按官网那种写法,官网是在Application注入,不适用原生这种集成方式。