1. 程式人生 > >window下Android專案整合React Native的正確姿勢

window下Android專案整合React Native的正確姿勢

      React Native的專案中分為Android與IOS,但是若在現有的Android專案中,整合RN,不能按照那個包結構來,我們統一在app資料夾下處理。

一、整合步驟:

   1.新增js檔案

      (1)在app資料夾下輸入命令 npm init,生成package.json檔案。這裡會讓你輸入name等資訊,除了name,其他可不輸入。開啟package.json檔案,在scripts節點下,新增如下程式碼,注意逗號隔開"test"節點。

"start": "node node_modules/react-native/local-cli/cli.js start"
     完整的package.json,我也貼出來:
{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^16.2.0",
    "react-native": "^0.52.1"
  }
}
 (2)安裝React 和React Native:app下繼續命令
npm install --save react react-native
      這裡需要一段時間,完成後,會在app目錄下生成一個node_modules資料夾。

       

 (3)配置其他檔案。

            a:將RN HelloWorld專案中的.flowconfig檔案和.watchmanconfig檔案拷貝過來;

            b:將RN HelloWorld專案中的index.js和App.js檔案拷貝過來,並將index.js檔案中註冊元件的名字與package.json中的名字一致(我使用的RN版本中已沒有index.android.js檔案了)。

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

2.專案配置

    (1)配置app下的build.gradle檔案。

 a:新增RN庫。

 b:處理RN引用的so檔案:RN中提供的libreactnativejni.so檔案是32位,而Android專案中用了一些64位的so檔案,導致不相容。解決辦法就是禁止使用那些64位的so檔案。

 c:appcompat-v7版本為23.0.1(只能使用該版本下的v7/v4包)。

      貼下整個的配置:

android{
    ndk {
     abiFilters "armeabi-v7a", "x86"
    }
}
packagingOptions {
   exclude "lib/arm64-v8a"
}
dependencies {
    compile "com.facebook.react:react-native:+" // From node_modules.
    compile 'com.android.support:appcompat-v7:23.0.1'
}

(2)專案的build.gradle中新增依賴
allprojects {
    repositories {
        google()
        jcenter()
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/app/node_modules/react-native/android"
        }
    }
}

3.建立Activity

 (1)建立MyRNActivity,繼承ReactActivity,重寫getMainComponentName()方法,返回值為package.json中的name值。

 (2)建立MyApplication,繼承Application,實現ReactApplication介面。

public class MyApplication 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;
    }
}

     (3)清單檔案註冊Activity和Application,並新增網路許可權和DevSettingsActivity。至此,整合結束。貼下整合的目錄:

   


二、執行

      先在app目錄下,啟動node.js。再執行Android專案就可以了。

npm  start

三、異常

 (1)v4/v7包版本不對,只能使用23.0.1版本構建。如果你用的是自己已釋出的專案,要注意引用庫中v4/v7包的版本,必要的時候,將引用庫中的v4/v7包排除掉。

IllegalAccessError: Method 'void android.support.v4.net.ConnectivityManagerCompat.<init>()

        (2)so檔案不統一。可以排除掉64位的so檔案,具體配置見第二節。

java.lang.UnsatisfiedLinkError: could find DSO to load: libreactnativejni.so

 (3)缺失 index.android.bundle檔案。

 Got JS Exception: ReferenceError: Can't find variable: __fbBatchedBridge 
--> Unable to load script from assets: index.android.bundle
 解決辦法: 手動新增assets目錄,建立index.android.bundle檔案,使用命令打包js到該檔案中。 
react-native bundle --entry-file index.js --bundle-output ./src/main/assets/index.android.bundle --platform android --assets-dest ./src/main/res/ --dev false

 (4) ReactNativeJS報錯

ReactNativeJS: undefined is not a function (evaluating '(d.remoteModuleConfig||[]).forEach(function(e,n){var t=u(e,n);t&&(t.module?v[t.name]=t.module:h(v,t.name,{get:function(){return l(t.name,n)}}))})')
 原因:專案下的build.gradle檔案,引用node_modules路徑錯誤,正確的如下:
maven {
    // All of React Native (JS, Android binaries) is installed from npm
    url "$rootDir/app/node_modules/react-native/android"
}

   

        (5)Cannot find entry file index.android.js in any of the roots。找不到index.android.js檔案。檢視官網的issue,找到了解決方案:複製index.js檔案,命名為index.android.js即可。    連結地址:https://github.com/facebook/react-native/issues/18217


發現的錯誤就是上述這些,最後貼一張效果圖: