美文网首页前端
原生Android应用中内嵌RN

原生Android应用中内嵌RN

作者: 佛系跳伞运动员 | 来源:发表于2018-04-11 14:46 被阅读68次

原生Android应用中内嵌RN

环境以及版本:
python v2.7.13 x64 |
node v6.10.3 |
npm v3.10.10 |
Android Studio v2.2.2 |
React v15.4.1 |
React-Native v0.39.2 |
Android-SDK 23


1.用AS新建原生Android空项目

  • 如图:

    图1
  • 创建完成后的文件目录结构如下:

    图2

2.使用npm在原生android根目录下初始化项目

$ npm init
  • 如图(注:name必须为全小写):

    图3
  • 修改package.json文件(这里之所以限定版本是因为不同版本之间可能会用兼容问题。在实际开发中发现"react": "15.4.1"与"react-native": "0.39.2"可以兼容)

"scripts": {
  "start": "node node_modules/react-native/local-cli/cli.js start"
}
"dependencies": {
  "react": "15.4.1",
  "react-native": "0.39.2"
}
  • 修改后如下

    图4

3.使用npm安装

$ npm install

安装过程中的报错信息,例如require react@某.某.某版本, but none was installed 说明react 和 react-native的版本不兼容需更换版本(测试中react 15.4.1 和react-native 0.39.2是兼容的)

  • 出现以下情况说明下载成功,项目下会多一个node_modules里面就是react 和rn相关

    图5

4.新建.flowconfig文件

在项目根目录下新建.flowconfig文件

  • .flowconfig文件内容为:
[ignore]
; We fork some components by platform
.*/*[.]android.js

; Ignore templates for 'react-native init'
.*/local-cli/templates/.*

; Ignore the website subdir
<PROJECT_ROOT>/website/.*

; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/

; Ignore unexpected extra "@providesModule"
.*/node_modules/.*/node_modules/fbjs/.*

; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
.*/Libraries/react-native/React.js
.*/Libraries/react-native/ReactNative.js

[include]

[libs]
Libraries/react-native/react-native-interface.js
flow/

[options]
emoji=true

module.system=haste

experimental.strict_type_args=true

munge_underscores=true

module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'

suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe

suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-5]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-5]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError

unsafe.enable_getters_and_setters=true

[version]
^0.45.0

5.项目根目录下新建 index.android.js

'use strict';

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

class HelloWorld extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.hello}>Hello, World</Text>
      </View>
    )
  }
}
var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  hello: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
});

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

6.修改app中build.gradle文件

  • 文件位置

    图6
  • 将app中build.gradle文件修改为:

配置文件中最大版本不能超过23最低不能低于16,添加以下信息到相应位置.

图7

7.为 React Native 添加一个 maven 依赖的入口

allprojects {
    repositories {
        ...
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
    ...
}
  • 如下图:


    图8

8.在新建的原生android项目中新建一个用于装载RN的activity

  • activity内容如下:
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.KeyEvent;

import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;

/**
 * Created by jianghe on 2017/5/11.
 */
public class MyReactActivity extends Activity implements DefaultHardwareBackBtnHandler {
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;

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

        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModuleName("index.android")//制定ReactInstanceManager对应的js文件
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        // 注意这里的HelloWorld必须对应“index.android.js”中的
        // “AppRegistry.registerComponent()”的第一个参数
        mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorld", null);
        setContentView(mReactRootView);
    }
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
            mReactInstanceManager.showDevOptionsDialog();
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }

    @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();
        }
    }

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

9.修改android清单文件

  • 如下图:

    图9

10.启动rn服务

$ npm start

补充个打包命令(将rn打包为bundle文件放入assets资源文件夹下)

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

后续会补充android+RN增量热更新以及预加载的文档

相关文章

网友评论

    本文标题:原生Android应用中内嵌RN

    本文链接:https://www.haomeiwen.com/subject/xozahftx.html