已有Android工程 集成React Native 的那些事

2017年2月27日,天氣晴,我永遠(yuǎn)記得這天,我心潮澎湃,因?yàn)榻K于把優(yōu)談TOP 集成了React Native,從去年開(kāi)始,公司陸陸續(xù)續(xù)的集成和學(xué)習(xí)React Native,通過(guò)demo的形式,寫(xiě)了不少組件和API,也能和后端調(diào)通,也多次,多個(gè)人嘗試把優(yōu)談TOP集成React Native,但是每次都是失敗的,因?yàn)槿鄙俳?jīng)驗(yàn),不能直接通過(guò)錯(cuò)誤判斷原因,只能通過(guò)Google查找各種資料,慢慢解決,下面記錄了我們,優(yōu)談TOP 原生 集成React Native 的那些事。也許也是你的那些事?

常規(guī)思路:

通過(guò)百度搜索 已有Android工程集成ReactNative 出現(xiàn)一大堆教程,大部分教程都是通過(guò)在原來(lái)的基礎(chǔ)上增加React Native的支持,比如這個(gè):《Android之原生項(xiàng)目集成React Native》 ,這也是官方推薦的集成方式,我也推薦這個(gè),只是我這樣,一直報(bào)錯(cuò),有一個(gè)啟動(dòng) MainaAtivity的錯(cuò),一直過(guò)不去,所以我就換一種思路。。。

在React Native基礎(chǔ)上增加原生

開(kāi)始通過(guò)官方文檔安裝和初始化React Native項(xiàng)目。

創(chuàng)建和運(yùn)行React Native 項(xiàng)目

react-native init UtanTop

cd UtanTop

react-native run-android

如果沒(méi)有錯(cuò),再繼續(xù)。如果有錯(cuò),說(shuō)明你環(huán)境都沒(méi)有安裝好,哈哈。請(qǐng)參考環(huán)境安裝文檔

恭喜你,第一步搞定了。接下來(lái),巨坑的地方要來(lái)了。

把原生的 build.gradle 文件先集成進(jìn)去

這一步比較簡(jiǎn)單,就是把gradle相關(guān)文件復(fù)制替換就可以了,你想的好簡(jiǎn)單哈。。。

我建議:

首先把原項(xiàng)目的gradle相關(guān)文件復(fù)制到新建的React Native項(xiàng)目,不要破壞原來(lái)的React Native項(xiàng)目的配置。

如果原生項(xiàng)目里有Module,先不要把Module導(dǎo)入,為了保險(xiǎn),把最簡(jiǎn)單的導(dǎo)入。

修改Root 目錄下的build.gradle

allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            url "http://192.168.1.205:8081/repository/utancenter/"
        }
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }

    }
}

如果有其他maven倉(cāng)庫(kù)直接這么寫(xiě)就可以了。

配置app目錄下的build.gradle
buildTypes {


//        release {
//            // 不顯示Log
//            buildConfigField "boolean", "LOG_DEBUG", "false"
//
//            minifyEnabled enableProguardInReleaseBuilds
//            zipAlignEnabled true
//            shrinkResources true
//            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
//            signingConfig signingConfigs.release
//
//            applicationVariants.all { variant ->
//                variant.outputs.each { output ->
//                    def outputFile = output.outputFile
//                    if (outputFile != null && outputFile.name.endsWith('.apk')) {
//
//                        //if ("woman".equals(WOMAN)){
//                        //  def fileName = "WomanTop_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
//                        //output.outputFile = new File(outputFile.parent+File.separator+"v"+defaultConfig.versionName, fileName)
//                        //} else {
//                        def fileName = "UtanTop_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
//                        output.outputFile = new File(outputFile.parent + File.separator + "v" + defaultConfig.versionName, fileName)
//                        //}
//
//
//                    }
//                }
//            }
//        }

        release {
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }

貼這個(gè)的意思就是先把打渠道包的去掉,使用React Native生成的配置,之后打渠道包在說(shuō),記得把下面幾段也要先注釋掉。


//    // 多渠道打包
//    productFlavors {

//        T1 {}
//        T2 {}
//        T3 {}
//
//    }
//
//    productFlavors.all { flavor ->
//        flavor.manifestPlaceholders = [CHANNEL_VALUE: name]
//    }


如果集成友盟的多渠道包,還需要在AndroidManifest.xml中注釋掉。

 <meta-data
            android:name="UMENG_APPKEY"
            android:value="${UMENG_APPKEY}" />

在這個(gè)時(shí)候我們還沒(méi)集成源碼,再執(zhí)行:

react-native run-android

如果編譯通過(guò),恭喜你,如果沒(méi)有過(guò)那是正常的,因?yàn)檫€有一個(gè)坑。

我的報(bào)錯(cuò)信息是


* What went wrong:
Execution failed for task ':app:packageAllDebugClassesForMultiDex'.
> java.util.zip.ZipException: duplicate entry: bolts/AggregateException.class

是因?yàn)閷?dǎo)入了重復(fù)的條目。

可能是在某些某些gradle版本才有吧。。。

我的解決方法:

    compile('com.facebook.fresco:fresco:0.10.0') {
        exclude group: 'com.parse.bolts',
                module: 'bolts-android'
    }

    compile ('com.facebook.fresco:animated-gif:0.10.0'){
        exclude group: 'com.parse.bolts',
                module: 'bolts-android'
    }

這時(shí)候再執(zhí)行:

react-native run-android

現(xiàn)在問(wèn)題應(yīng)該不大了,按道理可以運(yùn)行起來(lái)了,反正我的運(yùn)行起來(lái)了,但是還沒(méi)有加入源碼。。。

現(xiàn)在就把java res libs assets 目錄下的文件和 AndroidManifest.xml 復(fù)制到React Native項(xiàng)目中。

MainApplication 集成你原生項(xiàng)目的Application

一般項(xiàng)目都會(huì)自定一個(gè)Application

public class MainApplication extends UtanToutiaoApp 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);
  }
}

注意:不要把MainActivity MainApplication ,文件覆蓋了。

再執(zhí)行:

react-native run-android

應(yīng)該可以成功了,如果默認(rèn)啟動(dòng)的是MainActivity,那展示的就是React Native 界面,如果默認(rèn)不是MainActivity,那就通過(guò)下面的方式啟動(dòng)。


Intent i = new Intent(context, MainReactActivity.class);
    
context.startActivity(i);

到這里我反正就ok了,不知道你ok了沒(méi)?

如果不OK ,請(qǐng)留言,一起探討。。

還有我在學(xué)習(xí)和使用React Native 之后也會(huì)貼出來(lái)供大伙參考。。請(qǐng)關(guān)注 quanke

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,094評(píng)論 25 709
  • 英語(yǔ)太爛,菜鳥(niǎo)水平,如有不妥之處,請(qǐng)各位大神指正 工作原理 React Native應(yīng)用程序由JavaScript...
    Juice_gg閱讀 3,846評(píng)論 0 4
  • 當(dāng)時(shí)遇見(jiàn)他的時(shí)候,我還有喜歡的人,因?yàn)樵谝黄鹜鎯?,ktv里他打聽(tīng)我的名字,結(jié)果他死黨跟他說(shuō)我已經(jīng)有對(duì)象了,讓他別想...
    遠(yuǎn)惘閱讀 390評(píng)論 0 0
  • 門(mén)前、窗外有條歡快的小溪, 一年四季總以一樣的節(jié)奏 歡快的奔騰著。 你寂寞時(shí), 它會(huì)在那里陪著你。 在你開(kāi)心時(shí), ...
    Anand02閱讀 235評(píng)論 0 2
  • 以”支付寶”為代表的第三方支付在互聯(lián)網(wǎng)時(shí)代專(zhuān)注于電商支付,以免費(fèi)轉(zhuǎn)賬等業(yè)務(wù)便利性帶來(lái)了大量的用戶(hù)。對(duì)于銀行的線下支...
    木夜溯閱讀 31,999評(píng)論 0 4

友情鏈接更多精彩內(nèi)容