摘要:在應(yīng)用內(nèi)添加依賴回到,到的文件級(jí)別的里添加依賴最后一行的就是我們新增的,注意這里的版本號(hào)要和里的一致。因此,建議用這樣的寫法,并檢查版本號(hào)是否和里的一致。
引言
React Native是現(xiàn)在移動(dòng)開發(fā)新的可選方案,也帶來了原屬于Web領(lǐng)域的React的優(yōu)秀開發(fā)特性。另一方面,React Native的技術(shù)棧一經(jīng)掌握,可以用于iOS、Android及Windows(見此)多個(gè)平臺(tái),即所說的“l(fā)earn once, write anywhere”。
開始使用React Native的問題如何使用React Native?參照官方指南,你會(huì)發(fā)現(xiàn)官方告訴你的是:請(qǐng)用react-native init命令來創(chuàng)建一個(gè)React Native項(xiàng)目。這個(gè)項(xiàng)目的根目錄結(jié)構(gòu)是這樣:
但是,以Android為例,一個(gè)普通原生項(xiàng)目的根目錄結(jié)構(gòu)卻是這樣(Android Studio 2.1.2):
可以看到,Android原生項(xiàng)目(上圖的Drill根目錄)平級(jí)于生成的React Native項(xiàng)目的android目錄。那么,如果一直以來都是Android原生開發(fā),現(xiàn)在想要引入React Native,考慮部分頁(yè)面用React Native實(shí)現(xiàn),應(yīng)該如何做呢?
這就是React Native植入原生應(yīng)用的問題。顯然,react-native init命令生成的項(xiàng)目在結(jié)構(gòu)上不太相符,它的出發(fā)點(diǎn)更像是“完全用React Native做一個(gè)多平臺(tái)應(yīng)用”,但我們可能需要的是“一個(gè)原生應(yīng)用但有部分內(nèi)容是用React Native做的”。
在本文的時(shí)間點(diǎn),React Native的最新版是0.27。官方對(duì)此已給出植入原生Android應(yīng)用的指南,但它不夠準(zhǔn)確,也缺少一些細(xì)節(jié)。因此,本文將提供一個(gè)React Native植入原生Android應(yīng)用的更詳細(xì)一點(diǎn)的流程。
如果你想了解iOS版的,可以閱讀這篇文章。
植入Android流程 基本環(huán)境這篇流程是windows及Android Studio,如果你已經(jīng)是一個(gè)Android Studio原生應(yīng)用開發(fā)者,以及Node.js用戶,那么所需的環(huán)境你基本已經(jīng)有了。詳情請(qǐng)參考windows環(huán)境搭建文字教程以及開始使用React Native,什么都沒有也沒關(guān)系,正好從頭搭建。
此外,Android模擬器使用了Genymotion,注冊(cè)后就可以供個(gè)人使用,會(huì)比官方模擬器性能要好一些。
新建Android項(xiàng)目讓我們從一個(gè)全新的Android原生應(yīng)用開始。
用Android Studio創(chuàng)建一個(gè)新項(xiàng)目,注意Minimum SDK應(yīng)設(shè)置為API 16及以上(React Native要求Android4.1以上的環(huán)境):
添加npm組件到Android原生項(xiàng)目的根目錄(也可以新建一個(gè)目錄,但根目錄比較常用)新建一個(gè)文件package.json,內(nèi)容如下(這里起名為react-native-module):
{ "name": "react-native-module", "version": "0.0.1", "private": true, "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start" }, "dependencies": { "react": "^15.1.0", "react-native": "^0.27.2" } }
下面的dependencies的內(nèi)容要如何得知呢?答案是參考react-native init生成的項(xiàng)目,畢竟版本號(hào)是會(huì)不斷更新的。如果你已經(jīng)init生成過項(xiàng)目,可以運(yùn)行react-native upgrade更新后再參考。
然后,在這個(gè)package.json的所在位置,執(zhí)行:
npm install
安裝好所需的npm組件。
添加index.android.js文件同樣在根目錄,增加一個(gè)文件index.android.js,這是React Native開發(fā)的具體內(nèi)容,是任意的,這里給一個(gè)簡(jiǎn)單的例子:
import React, { Component } from "react"; import { AppRegistry, StyleSheet, Text, View } from "react-native"; class App extends Component { render() { return (); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center", }, note: { fontSize: 20 } }); AppRegistry.registerComponent("react-native-module", () => App); acgtofe.com with react native
注意上面代碼最后的react-native-module這個(gè)名字比較重要,可以自定,但后面還會(huì)在其他地方用到,需要保持一致。
在Android應(yīng)用內(nèi)添加依賴回到Android Studio,到app的build.gradle文件(module級(jí)別的gradle)里添加依賴:
dependencies { compile fileTree(dir: "libs", include: ["*.jar"]) testCompile "junit:junit:4.12" compile "com.android.support:appcompat-v7:23.4.0" compile "com.facebook.react:react-native:0.27.2" }
最后一行的react-native就是我們新增的,注意這里的版本號(hào)要和package.json里的一致。
運(yùn)行一次Gradle Sync,你必然會(huì)得到這個(gè)錯(cuò)誤:
這是因?yàn)锳ndroid項(xiàng)目默認(rèn)的依賴包的源jcenter()并不包含最新版的React Native(它只到0.20.1)。新版的React Native都只在npm里發(fā)布,因此你需要增加一下依賴包的源,到根目錄的build.gradle文件(project級(jí)別的gradle)內(nèi)增加以下內(nèi)容(從官方的這句注釋也可以了解到這一點(diǎn)):
allprojects { repositories { jcenter() maven { // All of React Native (JS, Android binaries) is installed from npm url "$projectDir/../node_modules/react-native/android" } } }
這里的url路徑,將取決于你放置node_modules的位置(你可以根據(jù)需要選擇放置在其他地方)。以上是node_modules位于根目錄時(shí)的url路徑,把它改為"$rootDir/node_modules/react-native/android"也是可以的,它們等效。如何知道這個(gè)路徑寫對(duì)了呢?反復(fù)試就可以了,如果路徑不對(duì),Gradle Sync的時(shí)候一定會(huì)提示你前面的錯(cuò)誤。
你可能在很多別的地方看到的都是這樣的寫法:
compile "com.facebook.react:react-native:+"
不太建議這樣做,因?yàn)闆]有明確的版本號(hào),你無(wú)法讓系統(tǒng)幫你判斷前面的url路徑寫的是否正確。如果寫錯(cuò),Android將使用發(fā)布在jcenter()的舊版React Native,而這將引發(fā)其他錯(cuò)誤(見后文)。
新建React Native的Activity新建一個(gè)繼承自ReactActivity的activity(這里起名為LiveActivity),Android Studio會(huì)提醒你必須實(shí)現(xiàn)3個(gè)方法,一般寫成這樣:
public class LiveActivity extends ReactActivity { @Override protected String getMainComponentName() { return "react-native-module"; } @Override protected boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected ListgetPackages() { return Arrays. asList( new MainReactPackage() ); } }
getMainComponentName()的字符串返回值,必須和前面的index.android.js內(nèi)的組件名一致。
getUseDeveloperSupport()是一個(gè)邏輯返回值,表示是否啟用開發(fā)者模式。這里寫BuildConfig.DEBUG就可以自動(dòng)根據(jù)gradle構(gòu)建的類型(debug或release)來決定。
getPackages是模塊列表,一般像上面代碼這樣就可以。如果你需要在JavaScript里調(diào)用原生Java模塊,就要把它們添加到這里,具體可以參考這篇文章。
清單文件添加聲明到Android清單文件AndroidManifest.xml添加以下內(nèi)容(省略了無(wú)關(guān)部分):
...
前面的權(quán)限都是React Native開發(fā)環(huán)境需要用到的。后面的LiveActivity是剛才的React Native運(yùn)行界面,DevSettingsActivity則是以下這個(gè)Dev Settings的界面:
它也是開發(fā)版所必需的。
啟動(dòng)packager server到package.json的位置,打開命令行,運(yùn)行packager server:
react-native start
也可以用npm start。啟動(dòng)后的狀態(tài)看起來像這樣:
運(yùn)行起來這是最后一步了。build這個(gè)Android項(xiàng)目,安裝到模擬器里,然后打開應(yīng)用,切換到LiveActivity界面(用按鈕跳轉(zhuǎn),或者直接設(shè)置為啟動(dòng)界面都可以),這時(shí)候應(yīng)該只看到一片空白。
按ctrl + m(這是Genymotion的用法,事實(shí)上,這是Android的Menu鍵,現(xiàn)在的實(shí)體設(shè)備基本沒有這個(gè)鍵,但搖一搖可以觸發(fā))開啟調(diào)試菜單,選擇Dev Settings,打開前面貼過圖的DevSettingsActivity,設(shè)置Debug server host & port for device為本機(jī)ip地址(命令行內(nèi)ipconfig查看)。最后,回到LiveActivity,開啟調(diào)試菜單選擇Reload JS,等待一會(huì)兒,如果你看到了像下圖這樣的界面:
就說明完成了!對(duì)應(yīng)的,packager server里應(yīng)該可以看到每一次請(qǐng)求的記錄:
接下來,你就可以開始React Native的開發(fā)了,改動(dòng)保存后,重新Reload JS,就可以看到新的效果。
建議及改進(jìn)建議使用Android 5.0+的設(shè)備(包括模擬器),它們支持直接USB傳輸packager server返回的那個(gè)bundle js文件。如果是Android 5.0+,可以USB連接電腦后(如果是模擬器,那就等于已經(jīng)連接)運(yùn)行以下命令:
adb reverse tcp:8081 tcp:8081
然后就可以省略掉前面流程里設(shè)置本機(jī)ip地址那一步,直接Reload JS。注意設(shè)備需要開啟USB調(diào)試(模擬器不用),而且電腦同時(shí)只連接一個(gè)設(shè)備。
相對(duì)于前面設(shè)置本機(jī)ip地址的方式,這幫你免去了同一WiFi環(huán)境、代理等麻煩。
不順利的情況雖然流程看起來輕松愉快,但并不怎么能一次成功。下面是我在流程中碰到過的一些問題及其記錄,可以用作參考。
版本不匹配錯(cuò)誤提示如下:
參照github上的issue,這個(gè)錯(cuò)誤的引發(fā)原因是packager server的React Native版本和Android應(yīng)用內(nèi)的不一致。比如應(yīng)用內(nèi)的gradle依賴寫的是compile "com.facebook.react:react-native:+"但url路徑寫得不對(duì),結(jié)果用的就是jcenter()里的0.20.1的舊版,就會(huì)有這個(gè)問題。
因此,建議用compile "com.facebook.react:react-native:0.27.2"這樣的寫法,并檢查版本號(hào)是否和package.json里的一致。
404這是說index.android.js文件不存在的錯(cuò)誤。但我碰見的是文件就在那,也出這個(gè)錯(cuò)誤。
這可能是由不正確的緩存引起,我的解決方法:關(guān)閉server,刪除index.android.js,然后重啟server,刷新,得到真正的404,然后還原index.android.js,再刷新即解決。
無(wú)法連接到server先按照Try the following to fix the issue: 下給出的解決方法依次檢查和嘗試。如果仍不能解決,刪除掉node_modules目錄,重新npm install,然后重開server。
windows下刪除node_modules目錄可能有路徑過長(zhǎng)的問題,推薦用rimraf來刪除。
500這個(gè)問題需要具體看server的輸出,我這里的錯(cuò)誤信息是:Error: Unable to find file with path: ......polyfillsprelude_dev.js。類似前面的無(wú)法連接server,我也是刪除node_modules后重新安裝得到解決。
有用的調(diào)試方法流程中可能碰到的問題可以分為兩類,Android應(yīng)用(client)和server。如果看到錯(cuò)誤,打開瀏覽器訪問http://localhost:8081/index.android.bundle?platform=android,如果能看到輸出的JavaScript代碼,那說明server是比較正常的,更可能是Android應(yīng)用的問題。反過來,如果瀏覽器里同樣看到錯(cuò)誤信息,那更可能就是server的問題。
沒有Flow和Nuclide你可能在開始用React Native的過程中聽說了Flow和Nuclide,它們分別是JavaScript類型檢查工具及React Native的推薦IDE。
但請(qǐng)注意,在本文的時(shí)間點(diǎn),它們還沒有windows版。我是用Atom來開發(fā)React Native的。
發(fā)布正式版React Native的開發(fā)版是需要有一個(gè)packager server來隨時(shí)發(fā)送更新后的bundle js文件的。但如果要得到真正簽名的正式版(app-release),你需要把bundle js文件保存到Android應(yīng)用的資源目錄內(nèi)。這樣,正式版不再需要server支持,可以獨(dú)立運(yùn)行。
參照官方的發(fā)行APK包指南,你只需要這樣幾步:
創(chuàng)建目錄app/src/main/assets。
運(yùn)行以下命令(對(duì)應(yīng)本文流程的目錄結(jié)構(gòu)),將bundle js文件保存到資源目錄。
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/
在Android Studio里選擇Build→Generate Signed APK...,生成正式版的apk。
官方有提到使用react.gradle文件的方法,但我覺得像上面這樣不用它更簡(jiǎn)單。
正式版的即時(shí)更新看起來正式版把bundle js文件保存到了apk內(nèi),這好像就丟失了React Native的即時(shí)更新?對(duì)的,但仍然有辦法實(shí)現(xiàn)它,你可以看看React-Native-Remote-Update,這個(gè)項(xiàng)目已經(jīng)過時(shí)了,但里面貼出的原理很值得參考。
現(xiàn)在,你可以用react-native-auto-updater來幫助你實(shí)現(xiàn)React Native的即時(shí)更新。
參考資料集我在寫本文的過程中參考了下面三個(gè)資料集合,覺得非常棒,在此也貼出來:
React-Native學(xué)習(xí)指南
Android開發(fā)技術(shù)周報(bào)特刊之React Native
react-native-android-guide
結(jié)語(yǔ)React Native的Android版本是去年9月(2015.9.15)才推出,此前只有iOS版。相對(duì)來說,Android的相關(guān)教程要比iOS少很多。因此,我覺得有這樣一份windows + React Native for Android的組合流程會(huì)很有幫助。
來嘗試新的移動(dòng)開發(fā)方案吧!
(重新編輯自我的博客,原文地址:http://acgtofe.com/posts/2016/06/react-native-embedding-android)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/79740.html
摘要:閱讀本期周刊,你將快速入門,開啟甜蜜之旅。然則的原理負(fù)責(zé)發(fā)送以及處理消息,創(chuàng)建消息隊(duì)列并不斷從隊(duì)列中取出消息交給,則用于保存消息。 showImg(/img/bVCN99?w=900&h=385); 2016 年 8 月,Android 7.0 Nougat(牛軋?zhí)牵┱桨l(fā)布,那么問題來了,你 Marshmallow 了么(? -? ?) Cupcake、Donut、Gingerbre...
摘要:接下來,我將從原理優(yōu)缺點(diǎn)等方面為大家分享跨平臺(tái)技術(shù)演進(jìn)。小程序年是微信小程序飛速發(fā)展的一年,年,各大廠商快速跟進(jìn),已經(jīng)有了很大的影響力。下面,我們以微信小程序?yàn)槔治鲂〕绦虻募夹g(shù)架構(gòu)。 前言 大家好,我是simbawu ,@BooheeFE Team Leader,關(guān)于這篇文章,有問題歡迎來這里討論。 隨著移動(dòng)互聯(lián)網(wǎng)的普及和快速發(fā)展,手機(jī)成了互聯(lián)網(wǎng)行業(yè)最大的流量分發(fā)入口。以及隨著5G...
閱讀 2135·2019-08-29 16:53
閱讀 2712·2019-08-29 16:07
閱讀 2054·2019-08-29 13:13
閱讀 3277·2019-08-26 13:57
閱讀 1342·2019-08-26 13:31
閱讀 2446·2019-08-26 13:22
閱讀 1232·2019-08-26 11:43
閱讀 2095·2019-08-23 17:14