Android 集成React Native 到現有的項目踩坑記錄

集成步驟

官方文檔:https://facebook.github.io/react-native/docs/0.54/integration-with-existing-apps
借鑑博客:https://blog.csdn.net/u012455...node

(1)配置react-native的開發環境
(2)建立一個react-native 的項目
(3)把項目中的android目錄裏面的東西換成現有的項目
(4)配置android項目的build.gradle文件以及各類依賴
(5)運行項目,運行服務,設置ip端口調試。
(6)各類踩坑問題,好比不支持64位手機的so庫問題,找不到服務,因爲react native 版本問題致使的各類錯誤等等

官方文檔的集成步驟;
一、安裝 node.js python2 jdk 8
這個安裝過程就不說了。網上一大堆
二、下載更新React Native CLI
命令:npm install -g react-native-cli
執行這行命令就可使用react-native 命令了。好比 使用命令運行
三、android 環境配置和模擬器或者手機鏈接
因爲我是作android的,因此這些就跳過了,不清楚的看官方文檔或者上網查
四、建立新的應用程序
重點來了,建立應用的時候執行命令:react-native init AwesomeProject 這裏的AwesomeProject是項目名稱能夠隨便換,可是必須以字母開頭。 因爲下載是在國外因此特別慢,因此咱們要添加如下國內鏡像。python

npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist

這兩個均可以,會顯著提升下載速度。設置了鏡像,而後再執行建立的命令。
五、運行新應用的採坑記錄
指定react 和react-native 的版本。
項目目錄下的 node_modules 文件夾是 reactnative 所依賴的js的一些東西。
若是沒有,咱們能夠再項目跟目錄執行 npm install 命令下載
這個時候咱們要注意一下版本號,由於這裏遇到坑了。目前最新的react--native多是0.56 會出現一個bug
好比最新版本react

react-native-cli: 2.0.1
react-native: 0.56.0

可是運行的時候出現 Unable to resolve module 'AccessibilityInfo' 這個錯誤,因此建議仍是版本低一點,這裏使用穩定版
在這裏插入圖片描述android

切換步驟:
(1)先將舊版卸載git

npm uninstall -g react-native-cli
npm uninstall -g react-native

(2)再安裝指定版本github

npm install -g react-native@0.55.4
npm install -g react-native-cli@1.2.0

能夠再項目初始化的時候指定下,不指定的話,只要版本對也沒問題,本身查看下npm

react-native init --version="0.55.4" myFirstApp

六、解決紅屏錯誤:Module build failed: Error: Plugin 0 specified in 「base」 … provided an invalid property of 「default」
若是出現上面錯誤執行下面命令json

npm install --save-dev babel-preset-react-native@2.1.0

七、解決 React_Native 沒法運行再64位機器上
"/data/data/com.xxx.xxx/lib-main/libgnustl_shared.so" is 32-bit instead of 64-bit 這個錯誤
參考文章:https://blog.csdn.net/u013531824/article/details/53931307
Android不能同時加載32和64位本機庫。 若是您至少有一個依賴庫使用ARM64支持編譯的擴展,而另一些依賴庫僅支持ARM32,就會出現問題。 系統將檢測ARM64依賴關係,加載它,而後拒絕加載僅ARM32的so庫,就可能致使應用程序崩潰。
因此,要再項目中excute 64位的幾個so庫,使用32位的。
這個根據不一樣項目設置,查一下本身項目用到了哪些64位的so庫,都設置一遍
個人項目須要移除這些,而後就不報錯了。Native Libs Monitor 這個軟件很好用react-native

ndk {
            //設置支持的SO庫架構
            abiFilters 'armeabi', 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
        }

        packagingOptions {
            exclude "lib/arm64-v8a/libgnustl_shared.so"
            exclude "lib/arm64-v8a/libijkffmpeg.so"
            exclude "lib/arm64-v8a/libijkplayer.so"
            exclude "lib/arm64-v8a/libijksdl.so"
            exclude "lib/arm64-v8a/libimagepipeline.so"
            exclude "lib/arm64-v8a/librtmp-jni.so"

        }

八、把android 原生項目拷貝到reactnative 項目的android 目錄下
上面步驟能夠運行一個react-native 的簡單項目,接下來時怎麼集成到現有的Android 項目
react-native 項目結構以下:
在這裏插入圖片描述
咱們作android的話,是用Android studio 打開 android 這個目錄的。
六、修改gradle 的依賴配置
dependencies {}閉包下 全部的compile 替換位implementation 或者api由於個人Android studio是3.1.3,老報錯說compile 2018年末要刪除已廢棄。另外個人gradle是4.4 build gradle 工具 是3.1.3
(1)Android 項目根目錄的 build.gradle文件修改
以下:若是仍是不行,建議跟我同樣,加上google(). .可能若是是最新版 jencter有問題,用的時候調整下順序試一試。儘可能不要用最新版本的react-nativeapi

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
        //添加這個maven地址,否則沒法下載 react-native庫
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}

再app 的build.gradle 中添加依賴
使用api 或者implementation 均可以, 這裏我也制定了版本。

dependencies {
.........
api "com.facebook.react:react-native:0.55.4"
}

七、配置權限

<uses-permission android:name="android.permission.INTERNET" />
//我還要添加一個權限,建議也添加了
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

再調試的時候咱們通常須要訪問DevSettingsActivity,因此也須要添加到AndroidManifest.xml:
手機搖一搖,或者菜單,設置 電腦服務的ip地址和端口要用到

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

八、代碼集成
剛剛建立的最簡單的react-native 已經有了。咱們就再咱們Android 項目中加載這個最簡單的頁面

public class MyReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
    private final int OVERLAY_PERMISSION_REQ_CODE = 1;
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;
    @Override
    protected void onCreate(@Nullable 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();

        // 注意這裏的「FirstApp」必須
        // 對應index.js」中的「AppRegistry.registerComponent()」的第一個參數值
        // 對應「package.json」中的「name」屬性值
        // 最好也將「app.json」中的「name」和「displayName」改爲它
        mReactRootView.startReactApplication(mReactInstanceManager, "FirstApp", 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)) {

                }
            }
        }
    }
    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }

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

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

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

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }

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

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy(this);
        }
        if (mReactRootView != null) {
            mReactRootView.unmountReactApplication();
        }
    }
    @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);
    }
}

以上是個人activity,大概意思和官網同樣。。代碼直接複製就行,須要注意的是:
代碼制定的文件名必定要和 配置文件中的一致,要檢查
app.json中的name和displayName屬性值
ndex.js中registerComponent的第一個參數值
package.json中的name屬性值
這幾個值要保持一致

九、在真機上運行項目直接在 reat-native 項目根目錄運行命令 react-native run-android , 跳轉到上面activity而後運行起來若是是紅屏,說是連不上服務,就搖一搖手機,選擇 Debug server host 啥的,設置電腦的ip:8081 這樣就能打開了。或者,直接用Android studio 運行本身的Android 項目, 跳轉到上面react 的activity ,也能夠是fragment的。 若是出現錯誤,繼續百度谷歌解決。。。有坑是確定的嘛。先記錄這些

相關文章
相關標籤/搜索