Android Studio Android項目內嵌入React Native混合開發

簡介:React Native使你能夠在JavaScript和React的基礎上獲得完全一致的開發體驗,構建世界一流的原生APP。
React Native着力於提高多平臺開發的開發效率 —— 僅需學習一次,編寫任何平臺。(Learn once, write
anywhere) Facebook已經在多項產品中使用了React Native,並且將持續地投入建設React Native。


摘自——React Native 中文官網

站在巨人的肩膀上(感謝那些戰鬥在技術最前沿的大佬們)

創建項目(已有項目跳過)

新建項目

點擊下一步

設置最小API

下一步

選擇EmptyActivity 作爲項目的MainActivity的模板

下一步

項目創建完成

到這一步項目創建完成

下面要將React Native集成到上面的Android項目中

環境搭建

  • Python 2 安裝

python下載安裝

下載安裝完成之後,要添加環境變量

python環境變量配置

node.js安裝

召喚出cmd:輸入:python 回車提示你版本號就是安裝成功了

同樣Node.js需要環境配置

步驟一

步驟二

召喚出cmd:輸入:node -v 回車提示你版本號就是安裝成功了

  • React Native生成相應配置文件

    terminal中輸入命令

按順序執行下邊命令

npm init

npm install –save react react-native

react-native curl -o .flowconfig
https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig

init 主要根據提醒生成package.json文件

install –save react react-native 安裝React 和React Native

curl -o .flowconfig
https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig 下載.flowconfig文件

第一步:npm init 主要是填寫各種信息,生成package.json
一步一步操作;
這裏只貼一張圖下邊直接給出整個生成文件

圖片

D:\studioworkspace\ReactDemoOne>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (ReactDemoOne) reactdemoone
version: (1.0.0) 1.0.0
description: react demo first
entry point: (index.js) index.android.js
test command: no
git repository: no
keywords: no
author: yaodonglv
license: (ISC) ISC
About to write to D:\studioworkspace\ReactDemoOne\package.json:

{
  "name": "reactdemoone",
  "version": "1.0.0",
  "description": "react demo first",
  "main": "index.android.js",
  "scripts": {
    "test": "no"
  },
  "repository": {
    "type": "git",
    "url": "no"
  },
  "keywords": [
    "no"
  ],
  "author": "yaodonglv",
  "license": "ISC"
}


Is this ok? (yes) yes

第二步:npm install –save react react-native

此處可能很卡一直卡在某個地方
解決方法:
設置npm淘寶鏡像,在terminal中執行:
npm config set registry “https://registry.npm.taobao.org

下載node_modules

執行結束會多一個node_modules文件夾

react node_modules

第三步:添加.flowconfig文件

第一種方式執行:
curl -o .flowconfig
https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig 下載.flowconfig文件

第二種:(適用於第一種方法不能自動下載或出現問題的可以使用第二種)
首先在項目根目錄新建一個名字是.flowconfig的文件
https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig
然後,直接訪問以上鍊接複製其中的內容,複製到創建的.flowconfig文件中OK
生成.flowconfig文件

  • 文件內容配置

添加”start”: “node node_modules/react-native/local-cli/cli.js start” 到package.json 文件下 scripts標籤

{
  "name": "reactdemoone",
  "version": "1.0.0",
  "description": "react demo first",
  "main": "index.android.js",
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "repository": {
    "type": "git",
    "url": "no"
  },
  "keywords": [
    "no"
  ],
  "author": "yaodonglv",
  "license": "ISC",
  "dependencies": {
    "react": "^15.4.2",
    "react-native": "^0.41.2"
  }
}

添加 index.android.js 到項目中去(中間的android開頭小寫,編輯器直接給我改成大寫了)

'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);

添加後

APP中gradle配置

gradle第一步配置

React Native 支持23,23之上自己有興趣可以配置一下

圖中標記1處compileSdkVersion使用版本23
圖中標記2處buildToolsVersion使用版本23.0.1
圖中標記3處 minSdkVersion使用版本16
圖中標記4處targetSdkVersion使用版本23
圖中標記5處6處增加ndk支持

ndk {
   abiFilters "armeabi-v7a", "x86"
}

packagingOptions {
   exclude "lib/arm64-v8a"
}

解決
java.lang.UnsatisfiedLinkError: dlopen failed: “/data/data/com.microcity.reactdemoone/lib-main/libgnustl_shared.so”is 32-bit instead of 64-bit
找不到so我見問題
圖中標記7處
使用

configurations.all {
 resolutionStrategy.force'com.google.code.findbugs:jsr305:1.3.9'
}

解決錯誤Conflict with dependency’com.google.code.findbugs:jsr305’的問題

gradle2

如果你的和這個不一樣修改如下

compile 'com.android.support:appcompat-v7:23.0.1'
compile "com.facebook.react:react-native:+" //此處可寫具體版本號更好

整個項目中的 build.gradle

項目Gradle

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

添加網絡權限
<uses-permission android:name="android.permission.INTERNET"/>
到AndroidManifest.xml

確保這裏的react native是最新版本
react native

出現了問題如果版本低於正常版本非常多檢查:

maven {
    `url "$rootDir/../node_modules/react-native/android"`//地址是否正確
} 
修改url "$rootDir*/..*/node_modules/react-native/android"爲
url "$rootDir/node_modules/react-native/android"

添加Native Code (正式嵌入React Native)

之前官方提供的代碼要自己手寫很多容易出現很多錯誤:

public class MainActivity extends AppCompatActivity 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.js")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorld", null);

        setContentView(mReactRootView);
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause();
        }
    }

    @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 invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }

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

}

現在官網直接給出一個ReactActivity的基類,我們直接繼承就好了

package com.microcity.reactdemoone;
import com.facebook.react.ReactActivity;
import javax.annotation.Nullable;

public class MyReactActivity extends ReactActivity {
    @Nullable
    @Override
    protected String getMainComponentName() {
       return "HelloWorld";//這個在Registry.registerComponent註冊
    }
}

是不是很簡單

接下來還要添加一個Application,不添加會報錯

package com.microcity.reactdemoone;
import android.app.Application;
import com.facebook.react.*;
import com.facebook.react.BuildConfig;
import com.facebook.react.shell.MainReactPackage;
import java.util.Arrays;
import java.util.List;

/**
 * Created by Darksiderl on 2017/2/27.
 */
public class App extends Application implements ReactApplication {

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage()
            );
        }
    };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }

}

在AndroidManifest.xml中添加

android:name=".App"

AndroidManifest.xml

這裏我沒有直接將MyReactActivity做入口,而是從MainActivity點擊跳轉過去的。

我們這裏不用npm start 因爲容易卡在

Loading dependency graph, done.

這句話,不知道你們有沒有遇到

所以直接去運行你的項目

但是他會報一個這樣的錯誤:

Could not get BatchedBridge, make sure your bundle is packaged
correctly

表示他找不到bundle文件

解決方法

  1. 先去你的文件的main(android/app/src/main)下新建assets文件夾
  2. 然後執行:
$>react-native start
$>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/

運行的時候可能會出現問題:
‘react-native’ 不是內部或外部命令,也不是可運行的程序
或批處理文件。

解決

terminal 中 執行 npm install -g react-native-cli

然後再去試一下上邊的命令,就可以了
另外:

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/

這個命令中的app/src/main/assets/index.android.bundle路徑一定要寫對否則會報錯不會生成這個bundle文件

個人感覺這個是最行之有效的
其他還有兩種方法參考文末的文章

如果是真機(模擬器)的話還要運行

adb reverse tcp:8081 tcp:8081

以上運行的圖片

然後再次運行基本就沒什麼問題了,現在你就可以去搞混合開發了

如果是模擬器參考文末文章的末尾處有介紹此處只介紹真機

本文參考史上最詳細的Android原生APP中添加ReactNative 進行混合開發教程

發佈了27 篇原創文章 · 獲贊 11 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章