原生Android應(yīng)用中內(nèi)嵌RN

原生Android應(yīng)用中內(nèi)嵌RN

環(huán)境以及版本:
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空項(xiàng)目

  • 如圖:

    圖1
  • 創(chuàng)建完成后的文件目錄結(jié)構(gòu)如下:

    圖2

2.使用npm在原生android根目錄下初始化項(xiàng)目

$ npm init
  • 如圖(注:name必須為全小寫(xiě)):

    圖3
  • 修改package.json文件(這里之所以限定版本是因?yàn)椴煌姹局g可能會(huì)用兼容問(wèn)題拍皮。在實(shí)際開(kāi)發(fā)中發(fā)現(xiàn)"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

安裝過(guò)程中的報(bào)錯(cuò)信息饿幅,例如require react@某.某.某版本, but none was installed 說(shuō)明react 和 react-native的版本不兼容需更換版本(測(cè)試中react 15.4.1 和react-native 0.39.2是兼容的)

  • 出現(xiàn)以下情況說(shuō)明下載成功,項(xiàng)目下會(huì)多一個(gè)node_modules里面就是react 和rn相關(guān)

    圖5

4.新建.flowconfig文件

在項(xiàng)目根目錄下新建.flowconfig文件

  • .flowconfig文件內(nèi)容為:
[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.項(xiàng)目根目錄下新建 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文件修改為:

配置文件中最大版本不能超過(guò)23最低不能低于16,添加以下信息到相應(yīng)位置.

圖7

7.為 React Native 添加一個(gè) maven 依賴(lài)的入口

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


    圖8

8.在新建的原生android項(xiàng)目中新建一個(gè)用于裝載RN的activity

  • activity內(nèi)容如下:
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對(duì)應(yīng)的js文件
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        // 注意這里的HelloWorld必須對(duì)應(yīng)“index.android.js”中的
        // “AppRegistry.registerComponent()”的第一個(gè)參數(shù)
        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.啟動(dòng)rn服務(wù)

$ npm start

補(bǔ)充個(gè)打包命令(將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/

后續(xù)會(huì)補(bǔ)充android+RN增量熱更新以及預(yù)加載的文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末厂僧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子黎炉,更是在濱河造成了極大的恐慌玷室,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篮幢,死亡現(xiàn)場(chǎng)離奇詭異大刊,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)三椿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)缺菌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人搜锰,你說(shuō)我怎么就攤上這事伴郁。” “怎么了蛋叼?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵焊傅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我狈涮,道長(zhǎng)狐胎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任歌馍,我火速辦了婚禮握巢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘松却。我一直安慰自己暴浦,他們只是感情好溅话,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著肉渴,像睡著了一般公荧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上同规,一...
    開(kāi)封第一講書(shū)人閱讀 51,165評(píng)論 1 299
  • 那天循狰,我揣著相機(jī)與錄音,去河邊找鬼券勺。 笑死绪钥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的关炼。 我是一名探鬼主播程腹,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼儒拂!你這毒婦竟也來(lái)了寸潦?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤社痛,失蹤者是張志新(化名)和其女友劉穎见转,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蒜哀,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡斩箫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撵儿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乘客。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖淀歇,靈堂內(nèi)的尸體忽然破棺而出易核,到底是詐尸還是另有隱情,我是刑警寧澤浪默,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布牡直,位于F島的核電站,受9級(jí)特大地震影響浴鸿,放射性物質(zhì)發(fā)生泄漏井氢。R本人自食惡果不足惜弦追,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一岳链、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧劲件,春花似錦掸哑、人聲如沸约急。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)厌蔽。三九已至,卻和暖如春摔癣,著一層夾襖步出監(jiān)牢的瞬間奴饮,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工择浊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留戴卜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓琢岩,卻偏偏與公主長(zhǎng)得像投剥,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子担孔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容