React-Native集成到現有的安卓項目中(坑死了)

React-Native集成到現有的安卓項目中

RN集成到ios的參見上一篇:https://github.com/ZhangMingZhao1/MingZhao-s-blog/issues/1java

畢竟要作跨端,ios調研完了安卓還要再去跑通一下,弄下來感受安卓比ios更坑一點。RN如今對版本的依賴太固定了,網上問題的教程也太少,版本不同就不適用了。node

1.

按照官網配置相關環境,後面的項目教程就不要跟着官網了,對新手不友好,適合會點原生的開發者,https://reactnative.cn/docs/getting-started/,
安裝Android Studio,第一次打開會下載相關的SDK,按照官網教程來,還有JDK,配置環境變量。react

用AS建立一個empty activity的項目,android

2.

在Android工程中 打開Terminal窗口,npm init,npm install –save react react-native,這樣默認下載的最新版,若是出現rn須要哪一個版本react支持就install @xx.xx版本的。ios

就在版本這裏卡了好久,我這裏以前安裝的ios的版本git

"dependencies": {
    "react": "16.0.0",
    "react-native": "0.51.0"
  }

到後面在安卓裏增長activity的時候發現和教程的不同了,AS提示我要重寫函數,這個後面說。
因此我如今成功的版本是:github

"react": "^16.6.3",
"react-native": "^0.57.7"

3.

在項目的根目錄建立.flowconfig文件,該文件的內容能夠從Facebook 的GitHub上下載, 查看這裏, 將其內容copy進去便可;shell

4.

接下來在咱們項目的根目錄下的package.json文件中的scripts節點下添加改句:
"start": "node node_modules/react-native/local-cli/cli.js start"npm

在咱們的項目根目錄下添加index.js文件(老rn版本叫index.android.js),該文件便是咱們的RN界面,而後在該文件中添加咱們React Native界面的代碼,例如簡單的HelloWorld:
代碼以下:json

import React, { Component } from 'react';import { Text, AppRegistry } from 'react-native';

export default class App extends Component {
  render() {    return ( <Text>Hello world!</Text>);
  }}
AppRegistry.registerComponent('application', () => App);

5.

在android兩個build.gradle裏添加

dependencies {
    implementation 'com.android.support:appcompat-v7:26.1.0'(每一個人的版本這裏可能不同)
    implementation 'com.facebook.react:react-native:+'
}
allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "$rootDir/node_modules/react-native/android"
        }
    }
}

6.

添加NDK支持,若是不添加這句話的話,可能會形成關於32位和64位SO庫混合引入Crash:
i).在App 的build.gradle中的defaultConfig節點下添加以下語句:

ndk {
   abiFilters "armeabi-v7a", "x86"
}
即:
defaultConfig {
        applicationId "com.example.lance.myapplication"
        minSdkVersion 23
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
    }

ii).而後在咱們project下的gradle.properties文件中的末尾添加以下語句:
android.useDeprecatedNdk=true

iii).在App的build.gradle文件的android節點下添加:
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
}

7.

完成以上步驟後,React Native就算集成到咱們現有的Android項目中,接下來咱們用Activity來展現咱們的RN:

新版本中的ReactNative只須要自定義一個Activity,並將其集成ReactActivity,實現getMainComponentName()方法,在該方法中返回一開始咱們註冊的ReactNative的名稱便可(即跟咱們的index.js中的AppRegistry中的第一個參數相同),在ReactActivity中,已經幫咱們實現了ReactRoot與ReactInstanceManager的配置,在以前的版本中,ReactRoot與ReactInstanceManager須要咱們本身去寫:
完成上面後,咱們在android裏main裏新增一個activity:

package com.example.zhangmingzhao.rnandroid;

import javax.annotation.Nullable;

import com.facebook.react.ReactActivity;

public class MyReactActivity extends ReactActivity {
    @Nullable
    @Override
    protected String getMainComponentName() {        return "application";   //application即註冊ReactNative時的名稱;
    }
}

這裏就是我上面說的遇到的版本的坑,我以前裝的ios的版本的rn的時候,重寫getMainComponentName後AS還報錯提示我要重寫一些其餘方法,可能就是版本的問題。

8.

接下來建立一個MyApplication,並初始化一個ReactNativeHost,該MyApplication繼承Application並實現ReactApplication,在源碼loadApp方法時,會將當前的Activity的Application強制轉換成ReactApplication:

package com.example.zhangmingzhao.rnandroid;

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 MyApplication extends Application implements ReactApplication {

    private final ReactNativeHost reactNativeHost = 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 reactNativeHost;
        }
        @Override
        public void onCreate() {
            super.onCreate();
            SoLoader.init(this,false);
        }
}

注意有的包option + 回車會提示多個,注意引對。
(這裏寫的getUseDeveloperSupport好像就是我上部低版本rn下要提示額外重寫的方法?)

9.

在原生中加一個按鈕,在 MainActivity 添加一個按鈕跳轉到 MyReactActivity,首先在 app/src/main/res/layout 下的 activity_main.xml 添加一個按鈕元素

<Button
    android:id="@+id/btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="點擊跳轉到RN界面"/>

在 MainActivity 裏添加點擊跳轉事件

package com.example.zhangmingzhao.rnandroid;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 點擊按鈕跳轉到 react-native 頁面
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this,MyReactActivity.class));
            }
        });
    }
}

10.

最後在 app/src/main/AndroidManifest.xml 文件中,添加一些權限,以及聲明MainApplication 跟 MyReactActivity

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.zhangmingzhao.rnandroid">

    <uses-permission android:name="android.permission.INTERNET"/>   <!-- 網絡權限 -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <!-- 彈框權限 -->
    <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/> <!-- 窗體覆蓋權限 -->
    <!-- 聲明MainApplication -->
    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- 聲明MyReactActivity -->
        <activity
            android:name=".MyReactActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">
        </activity>
        <!-- 聲明能夠經過晃動手機或者點擊Menu菜單打開相關的調試頁面 -->
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
    </application>
</manifest>
  1. 這種方法下的必需要打包:
    咱們手動的在app/src/main/目錄中添加一個assets目錄, 並在該目錄下添加一個index.android.bundle文件, 而後手動在該bundle文件中添加內容, 執行如下命令:
react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/

聲明:

  1. --platform : 平臺(android/ios)
  2. --dev : 開發模式
  3. --entry-file : 條目文件
  4. --bundle-output : bundle文件生成的目錄
  5. --assets-dest : 資源文件生成的目錄

ios的npm start啓動,安卓模擬器也沒識別到,若是是dev模式的話還要另需配置,待我補充,因此整體安卓比ios仍是坑多了。

12.

打包後就能夠在AS中運行了。注意每次改動AS的配置,都要從新點下Sync
在這裏插入圖片描述

第一次建立,clone安卓項目也要Sync,還要下載一些東西,用公司內網是真的慢,我本身開的熱點。。

13

demo連接:
https://github.com/ZhangMingZhao1/react-native-pratice/tree/master/RNAndroid

整體安卓仍是比IOS坑一些,安卓集成RN這個待補充吧。

相關文章
相關標籤/搜索