React Native Android 开发巨坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/EI__Nino/article/details/85164794

〇. Android Native 接入 React Native

1. 基本配置规则

https://reactnative.cn/docs/integration-with-existing-apps/

2. 稍作优化

如果Native库用得太多,建议把package移出来


// 在 MainActivity.java 里面 新建 getPackages方法,把packages移出来
    protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                new ReactModulePackage(),
                new RNGestureHandlerPackage(),
                new RNFetchBlobPackage(),
                new RNSoundPlayerPackage(),
                new LottiePackage(),
                new LinearGradientPackage());
    }

在这段代码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        // 注意这里的MyReactNativeApp必须对应“index.js”中的
        // “AppRegistry.registerComponent()”的第一个参数
        mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);
        setContentView(mReactRootView);
    }

里面的 addPackage 改为 addPackages(getPackages)

2. 常规手动Link库

以巨坑 react-navigation为例子

1) 修改 settings.gradle

.....
include ':react-native-gesture-handler'
project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, 'node_modules/react-native-gesture-handler/android')

*注意目录地址,如果是普通RN项目,一般是相对路径 .../node_modules/,但是Native接入RN的话,一般RN代码已经是在Android的目录了,所以不加 ...,具体还是看项目结构 。引入各种库的时候,要时刻关注目录的问题。react-native link命令基本没法用,因为RN在这里不是一个Application,入口文件名也不一定是MainActivity.java,所以基本所有的Native库,都要手动Link.

2) 修改 app/build.gradle

dependencies {
    ....
    implementation project(':react-native-gesture-handler')
}

3) 修改 app/src/main/java/com.xxxx/MainActivity.java

...

import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
// 引入Package 
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
...

// 在 MainActivity.java 里面 加入Package
    protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                ...
                new RNGestureHandlerPackage(),
                new LinearGradientPackage());
    }

一. React Navigation

npm install --save react-navigation react-native-gesture-handler

*必须这俩都安装,记得link react-native-gesture-handler

在RN的Activity里面,比如MainActivity.java


mReactRootView = new ReactRootView(this);
替换为
mReactRootView = new RNGestureHandlerEnabledRootView(this);

二. Mobx

2018年12月21日写下此教程,前端一天,后端十年。辛苦了,我的前端工程师。

如果你看到此教程,那么你是幸运的,其他教程基本都不对。

扫描二维码关注公众号,回复: 4685974 查看本文章

1. 安装 mobx 和 babel

npm install --save mobx mobx-react @babel/core @babel/plugin-proposal-decorators @babel/runtime metro-react-native-babel-preset

2. 配置 `.babelrc’

(项目根目录,没有则创建)

{
  "presets": [
    "module:metro-react-native-babel-preset"
  ],
  "plugins": [
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": true
      }
    ]
  ]
}

3. 安装 jsc-android

不安装则会报 Can't find variable: symbol, Android的病,至于为什么,看文档吧

npm install --save jsc-android

说明文档 (https://github.com/react-community/jsc-android-buildscripts)
*注意在 build.gradle 里面不用删除这个 maven,如果是Native接入RN,还需要注意目录问题

 maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/node_modules/react-native/android"
        }

Native 通信

合理使用 startActivityForResult

MainActivity.java 需要重写 onActivityResult方法,以接收其他Activity传过来的数据。

可以定一个Module,执行 setResult方法将数据传回调用MainActivity的别的Activity

略略略

四. 图片文件索引

Android里面的相册CameraRoll获取到的文件uri 只是文件索引而非图片路径,如果需要转化成文件路径,需要用Native查一下

*注意 需要获取Context才可以查。这是一个同步操作。可以封装个React Module


//imageUri= "content://xxxxxxx/xxx/123123"
String[] proj = {MediaStore.Images.Media.DATA};

Uri uri = Uri.parse(imageUri);

Cursor cursor =getContext().getContentResolver().query(uri, proj, null, null, null);;

int colIndex =cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();

String imagePath = cursor.getString(colIndex);

猜你喜欢

转载自blog.csdn.net/EI__Nino/article/details/85164794