React-Native與安卓原生的混合開發
寫在前面
目前很多大廠APP(如淘寶、餓了麼、美團等等)並不是純原生Android&IOS,也不是純JS開發,而是Hybird APP開發,混合型優勢很多:比如熱更新,保證在一些類似雙十一的活動到來時能夠快速上線活動頁面,使用者不必再去更新APP。再來有效地減小了安裝包的體積大小,大部分的介面都位於伺服器端,本地只需要進行繪製。
1. 新建Android專案
我這裡使用之前的專案
2. 在專案根目錄引入React-Native模組
在專案根目錄開啟終端(tip:按住shift + 右鍵,選擇開啟dos視窗)
輸入
npm init
這裡輸入一些該專案的屬性,為了生成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