1. 程式人生 > >React-Native學習筆記——正確整合到現有Android工程中

React-Native學習筆記——正確整合到現有Android工程中

背景

我們可能需要將react-native整合到已有工程的某個module中,而不是從頭建立一個新工程。下面記錄了筆者一個demo的整合過程。

已有工程結構

下圖中,app為application型別module,rntrial為library型別的module,就是我用來整合react-native的

這裡寫圖片描述

準備工作

開始整合

1、移花接木

執行命令 :react-native init [工程名] 建立一個全新的rn工程,如下
(注意工程名在下圖示識的三個檔案中均有出現)

這裡寫圖片描述

刪掉這個新工程android目錄下的內容,將原工程根目錄的所有檔案拷貝到這個android目錄下
這樣原工程就變成了一個標準的rn工程,在工程根目錄下可以使用npm、react-native等命令來操作了

2、建立一個具有RN功能的Activity

rntrail目錄中的build.gradle如下

apply plugin: 'com.android.library'

android {
    compileSdkVersion 26



    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:0.5' androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2' api 'com.facebook.react:react-native:0.51.0' }

建立RntrialActivity作為rn的主介面,並實現DefaultHardwareBackBtnHandler,主要程式碼如下(請務必注意程式碼中的註釋

public class RntrailActivity extends Activity implements DefaultHardwareBackBtnHandler {

    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;
    private static final int OVERLAY_PERMISSION_REQ_CODE = 0x01;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //這裡不加許可權判斷 6.0或以上機型會閃退
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!Settings.canDrawOverlays(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                        Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
            }
        }
        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                //這是設定assets目錄下的打包過的js檔名 這個檔案可用命令生成 但除錯期間我們使用npm server動態注入 釋出時才將它打進assets
                .setBundleAssetName("index.android.bundle")
                //這裡設定js入口檔案 舊一點的api可能是setJSMainModuleName 但我的版本是0.51.0 取而代之的是setJSMainModulePath方法
                .setJSMainModulePath("index")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        // 注意這裡的“Rnfeel”必須
        // 對應index.js”中的“AppRegistry.registerComponent()”的第一個引數值
        // 對應“package.json”中的“name”屬性值
        // 最好也將“app.json”中的“name”和“displayName”改成它
        mReactRootView.startReactApplication(mReactInstanceManager, "Rnfeel", null);
        setContentView(mReactRootView);
    }

   ...

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!Settings.canDrawOverlays(this)) {
                    // SYSTEM_ALERT_WINDOW permission not granted...
                }
            }
        }
    }
}

3、檢查相關檔案內容

以下幾個檔案中的相關內容務必保證一致

app.json中的name和displayName屬性值

    {
      "name": "Rnfeel",
      "displayName": "Rnfeel"
    }

index.js中registerComponent的第一個引數值

   AppRegistry.registerComponent('Rnfeel', () => App);

package.json中的name屬性值

  "name": "Rnfeel",

4、在真機上執行和除錯

首先連線usb,一臺電腦只連一部手機(電腦上的模擬器也要關閉,不然有些操作會失敗)

執行命令:react-native run-android 將應用安裝到裝置上

這裡寫圖片描述

在編譯的同時會彈出node server的介面,這個服務可以通過usb繫結裝置實現js熱更新

這裡寫圖片描述

執行命令adb reverse tcp:8081 tcp:8081與裝置建立連線

修改js內容,搖晃手機彈出rn設定選單, 選擇reload更新介面

rn設定選單中選擇 Debug JS Remotely開啟遠端除錯

這裡寫圖片描述