1. 程式人生 > >React-Native與安卓原生的混合開發

React-Native與安卓原生的混合開發

寫在前面

目前很多大廠APP(如淘寶、餓了麼、美團等等)並不是純原生Android&IOS,也不是純JS開發,而是Hybird APP開發,混合型優勢很多:比如熱更新,保證在一些類似雙十一的活動到來時能夠快速上線活動頁面,使用者不必再去更新APP。再來有效地減小了安裝包的體積大小,大部分的介面都位於伺服器端,本地只需要進行繪製。

1. 新建Android專案

我這裡使用之前的專案
rn01

2. 在專案根目錄引入React-Native模組

在專案根目錄開啟終端(tip:按住shift + 右鍵,選擇開啟dos視窗)
輸入

npm init

rn02
這裡輸入一些該專案的屬性,為了生成package.json檔案的專案描述。
接下來引入rn的一些模組檔案

npm install --save react react-native

此時會在根目錄生成一個node_modules資料夾,存的是RN的一些模組檔案
結束後會輸出一些日誌資訊,如果出現版本問題需要重新下載,因為react-native對react的版本有嚴格要求,高於或低於某個範圍都不可以。

npm i -S [email protected]某.某.某版本//此處為提示的版本號

接下來開啟package.json檔案,在scripts模組下新增

"start": "node node_modules/react-native/local-cli/cli.js start"

我的package.json檔案

{
  "name": "plusclubrn",
  "version": "1.0.0",
  "description": "plusclub in rn",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "repository": {
    "type"
: "git", "url": "git+https://github.com/WithLei/plusClub.git" }, "keywords": [ "react", "native" ], "author": "renly", "license": "ISC", "bugs": { "url": "https://github.com/WithLei/plusClub/issues" }, "homepage": "https://github.com/WithLei/plusClub#readme", "dependencies": { "express": "^4.16.4", "react": "^16.6.3", "react-native": "^0.57.7" }, "devDependencies": {} }

在專案根目錄新建一個檔案index.android.js,並將以下程式碼拷貝進去

import React, {Component} from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View
} from 'react-native';
class HelloWorld extends Component {
    render() {
        return (
            <View style={styles.container }>
                <Text style={styles.hello}>Hello, World</Text >
                <Text style={styles.hello}>This is my first RN fixed Android Project</Text >
            </View >
        )
    }
}
var styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
    },
    hello: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
});
AppRegistry.registerComponent('HelloWorld', () => HelloWorld);

3.Native部分的配置

首先在app下的gradle新增依賴

    implementation 'com.facebook.react:react-native:+'

這個+替換為你的專案根檔案下node_modules/react-ative/android 下的react-native的版本

在專案目錄下的gradle新增以下

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            url "https://jitpack.io"
        }
        // 如果有多個maven依賴,需要分開新增
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            // 注意這裡和官網的是不一樣的,由於我們的node_modules在根目錄下,官方為
            url "$rootDir/node_modules/react-native/android"
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

宣告網路許可權:

<uses-permission android:name="android.permission.INTERNET"/>

建立一個容器類

public class MyReactActivity extends ReactActivity {
    @Nullable
    @Override
    protected String getMainComponentName() {
        return "HelloWorld";
    }
}

在清單檔案裡面宣告此Activity

<activity android:name=".MyRNActivity"
           android:label="@string/app_name"
           android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>

配置除錯的介面

<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

配置Application,繼承RN的Application

import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.List;
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;
    }

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

做一個跳轉,我選擇繫結到了原生的button上做響應事件

startActivity(new Intent(this, MyRNActivity.class));

執行APP

我們可以先把APP執行起來,跑在虛擬機器或者真機上
然後啟動伺服器:在專案根目錄下開啟終端執行

npm start

然後就可以運行了,中間有不少坑,碰到的時候沒截圖,之後參考了很多部落格和官方Issue解決了,這裡就不復現bug了。

參考部落格:
將RN嵌入到現有的Android應用中 - Byron_Walden
Guide文件 - React native中文網
Github issues - facebook