(最新react-native-0.59.5) 如何将ReactNative项目集成到现有得Android项目中(两种实现方法之一)

背景:最近在学习React-Native相关的知识,有个需求,如果已经存在一个成熟的Android 或者 IOS项目,如何实现在后续的开发中用RN来实现部分功能。再此我只是讲解一下Android demo的两种实现方法。

一· 官方实现(以RN项目为主体,将已有Android项目copy进来)

虽说是官方推荐实现,最开始我也是按照上面的教程,一步一步搭建环境,但是上面的内容有些更新不及时,而且有些坑,上面还有提及,所以在这里总结说明一下需要注意的地方,避免大家再次入坑。

1.准备工作

首先,环境搭建,可以参考React Native中文网 0.59来安装一些依赖的软件

2.创建 React Native项目目录结构

创建一个空目录用于存放React Native项目,在其中创建一个”/android"子目录,将你现有的Android项目,放到这个子目录中

3. 安装 JavaScript 依赖包

a. 在项目跟目录下创建文件 ”package.json",了解package.json, 添加如下内容

每个项目的根目录下面,一般都有一个package.json文件,定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。npm install命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境。

{
  "name": "android_with_rn",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^16.8.6",
    "react-native": "^0.59.5"
  }
}

b. 然后,在当前项目目录(包含package.json)中,打开终端/命令提示行,通过npm(node 包管理工具)来安装React和React Native模块,运行命令“npm install”,这些模块会被安装根目录的“node_modules"目录中(这个目录我们原则上不复制、不移动、不修改、不上传,随用随装)

把node_modules/目录记录到.gitignore文件中(即不上传到版本控制系统,只保留在本地)。

npm install --save react react-native

4. 配置Maven

a. 在已经存在的Android 项目的app build.gradle 文件添加 React Native 依赖:

  • 如果想要指定特定的 React Native 版本,可以用具体的版本号替换 +,当然前提是你从 npm 里下载的是这个版本。
  • 注意该版本号需要与package.json文件中配置的RN版本号保持一致。
    之所以需要在项目的build.gradle文件中添加maven配置,是因为Android项目默认的依赖包的源jcenter()并不包含最新版的React Native(它只到0.20.1)
dependencies {
     ...
     implementation "com.facebook.react:react-native:+" // From node_modules.
 }

b. 在已经存在的Android 项目的 build.gradle 文件添加 React Native 的 Maven 依赖的入口,必须写在 “allprojects” 代码块中

allprojects {
    repositories {
        maven {
            url "$rootDir/node_modules/react-native/android"
        }
        jcenter()
        google()
    }
}

5. 配置权限

a. 在 AndroidManifest.xml 添加权限声明:


如果需要访问 DevSettingsActivity 界面(即开发者菜单),则还需要在 AndroidManifest.xml 中声明下面权限,开发者菜单一般仅用于在开发时从 Packager 服务器刷新 JavaScript 代码,所以在正式发布时你可以去掉这一权限。




b. Android6.0 及以上需要添加动态权限申请悬浮窗权限(overlay)

public class MainActivity extends AppCompatActivity {

    static final int OVERLAY_PERMISSION_REQ_CODE = 1000;
    private AppCompatButton mBtnRn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initEvent();
    }
    private void initEvent() {
        initView();
        checkAppPermission();
    }
    @SuppressLint("WrongViewCast")
    private void initView() {
        mBtnRn = findViewById(R.id.btn_rn);
        mBtnRn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转RN页面
                startActivity(new Intent(MainActivity.this, BaseRnActivity.class));
            }
        });
    }
    private void checkAppPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!Settings.canDrawOverlays(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                        Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
            }
        }
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!Settings.canDrawOverlays(this)) {
                    //SYSTEM_ALERT_WINDOW被拒绝
                }
            }
        }
    }
}

6. 集成RN 代码

a. 创建一个index.js文件(注意在 0.49 版本之前是 index.android.js 文件)

index.js是 React Native 应用在 Android 上的入口文件。而且它是不可或缺的!它可以是个很简单的文件,简单到可以只包含一行require/import导入语句。本教程中为了简单示范,把全部的代码都写到了index.js里(当然实际开发中我们并不推荐这样做)。

Index.js

import React from 'react';
import {AppRegistry, StyleSheet, Text, View} from 'react-native';

class HelloWorld extends React.Component {
  render() {
    return (
      
        RN 项目
      
    );
  }
}
var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  hello: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
});

AppRegistry.registerComponent('Android_With_RN', () => HelloWorld);

b. 应用中添加一个RCTRootView。这个RCTRootView正是用来承载你的 React Native 组件的容器。

注意1:官方推荐不是最新版本,最新RN(0.59.5)不需要自己实DefaultHardwareBackBtnHandler,只要集成ReactActivity,最新版本0.59.5 ,在ReactActivity中,已经帮我们实现了ReactRoot与ReactInstanceManager的配置

public class MyReactActivity extends ReactActivity {
    @Nullable
    @Override
    protected String getMainComponentName() {
        return "Android_With_RN";
    }
    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
        return new ReactActivityDelegate(this,getMainComponentName());
    }
}

我们需要在AndroidManifest.xml 把 MyReactActivity 的主题设定为 Theme.AppCompat.Light.NoActionBar ,因为里面有许多组件都使用了这一主题。



c. 实现ReactApplication

注意2:这一点和React Native中文网没有提到

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }
    @Override
       protected String getJSMainModuleName() {
           return "index";
    }
    @Override
    protected List getPackages() {
      return Arrays.asList(
          new MainReactPackage()
       );
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
    
  }
  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
  }
}

在AndroidManifest 配置MainApplication


d. 在 Android Studio 中打包

你也可以使用 Android Studio 来打 release 包!其步骤基本和原生应用一样,只是在每次编译打包之前需要先执行 js 文件的打包(即生成离线的 jsbundle 文件)。具体的 js 打包命令如下:

注意:bundle文件路径,把上述命令中的路径替换为你实际项目的路径。如果 assets 目录不存在,则需要手动的在app/src/main/目录中添加一个assets目录。

react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/

–platform : 平台(android/ios)
–dev : 开发模式
–entry-file : 条目文件
–bundle-output : bundle文件生成的目录
–assets-dest : 资源文件生成的目录

如果打包成功,会显示

Loading dependency graph, done.
bundle: start
bundle: finish
bundle: Writing bundle output to: app/src/main/assets/index.android.bundle
bundle: Done writing bundle output

7. 运行

在RN运行命令,运行到android设备中

react-native run-android 

未完待续 下一篇讲解 另一种实现方式点我

你可能感兴趣的:(React-Native)