React Native在Android當中實踐(一)——背景介紹
React Native在Android當中實踐(二)——搭建開發環境
React Native在Android當中實踐(三)——整合到Android專案當中
React Native在Android當中實踐(四)——程式碼整合
React Native在Android當中實踐(五)——常見問題
常見問題
若出現libgnustl_shared.so" is 32-bit instead of 64-bit類似錯誤
這個問題是由於ReactNative相容64位Android手機導致的。 解決辦法: 1.在專案的根目錄的 gradle.properties 裡面新增一行程式碼 android.useDeprecatedNdk=true. 2.在 build.gradle 檔案裡新增以下程式碼android {
defaultConfig {
ndk {
abiFilters "armeabi-v7a", "x86"
}
packagingOptions {
exclude "lib/arm64-v8a/librealm-jni.so"
}
}
}
複製程式碼
若出現react-native run-android Android project not found
出現這個問題主要是因為android專案的目錄結構跟react-native支援的目錄結構不一致導致的。 提示:當然了你也可以執行“react-native upgrade”,該命令執行之後你會發現你的android專案的目錄結構變化了。 之後 在執行react-native run-android即可。若出現Could not get BatchedBridge, make sure your bundle is packaged correctly
這是因為bundle沒有打包好。找不到編譯打包後的js檔案。其實就是android studio預設的尋找js檔案地址和react-native自己的工具編譯所使用的地址不同。若出現Could not connect to development server
首先 我們先翻譯一下 連線不到開發的伺服器。 請按照以下的步驟來修復此問題: 確保包伺服器在執行 確保你的裝置或者模擬器連線著電腦,並且手機開啟了USB除錯模式,然後在cmd中執行adb devices來檢視已經連線好的裝置列表 確保飛航模式是關閉的 如果是使用真機來開發,輸入 adb reverse tcp:8081 tcp:8081來檢查裝置 輸入IP:8081(這個大家都會) 解決辦法: 1、首先檢查包伺服器是否執行正常。 在專案資料夾下輸入react-native start或者npm start均可開啟伺服器,但是我們需要在PC端確認包伺服器是否執行正常。檢查網址為:http://localhost:8081/index.android.bundle?platform=android (1)說說我遇到的問題,開啟包伺服器之後,cmd中顯示如下: 出現React packager ready就走不動了。 當我看開http://localhost:8081/index.android.bundle?platform=android網址 時,沒有正常顯示,但是也沒 有顯示“該網頁無法訪問”,只是一直在轉圈圈重新整理網頁,就是打不開。 包伺服器中使用到了node,所以應該和node版本和配置有一定的關係。所以我就卸掉 node,重新安裝了最新版本的node,之後包伺服器開啟,網頁可以正常訪問,如下所示: 2、檢查硬體連線,以及使用adb devices來檢視是否連線成功。3、飛航模式關閉
4、在cmd中輸入 adb reverse tcp:8081 tcp:8081,結果如下:
個人認為解決辦法如下: 手機-設定-應用程式-開發-usb除錯開啟再關閉一次 重啟手機,usb除錯開啟再關閉一次 在cmd下Try "adb kill-server" and then "adb start-server" 本人測試機為android 5.0+系統,使用第二種方法解決問題。結果如下: 5、搖一搖手機選擇Dev Settings 輸入IP:8081。Make sure your bundle is packaged correctly or your're running a packager server
出現這個問題是由於index.android.bundle是用來呼叫原生控制元件的js指令碼,每次當改變了 index.android.js,都需要使用上面的程式碼片段,來及時的更新index.android.bundle,然後打包才可以把新的index.android.js應用上,所以當沒有index.android.bundle檔案時,React-Native 專案是無法執行的。
解決辦法是
第一步:在Android/app/src/main目錄下建立一個空的assets資料夾(若已經存在請忽略) 出現這個問題是由於
index.android.bundle是用來呼叫原生控制元件的js指令碼,每次當改變了 index.android.js,都需要使用上面的程式碼片段,來及時的更新index.android.bundle,然後打包才可以把新的index.android.js應用上,所以當沒有index.android.bundle檔案時,React-Native 專案是無法執行的。
解決辦法是
第一步:在Android/app/src/main目錄下建立一個空的assets資料夾(若已經存在請忽略)
第二步:在Android Studio的Terminal進入專案根目錄執行下面程式碼:
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/
執行完畢後可以看到如下表示已經成功了
同時在assets資料夾下會多出index.android.bundle和index.android.bundle.meta兩個檔案 如果已經有了資原始檔,但是依舊有以上提示,那麼對於真機來說搖晃手機會出現一些介面 選擇最後一個 進入如下介面 輸入本機的ip地址(注意手機和電腦在一個區域網) 別忘了加上埠號8081 如圖 確認之後返回然後搖動開啟除錯頁面選擇 重新載入之後,就會出現我們期盼已久的“Hello,World”React Native的開發者模式
會發現頂部有這樣的一條 這是正在從網路載入相關內容,當我們修改的時候,內容也會有相應的修改。但是如果網路狀況不太好的時候,想必會對我們的使用者體驗造成不小的影響。寫在最後
從我個人用 React Native 開發 APP 的體驗來看,React Native 適合 C/S 結構、業務型的 APP 或其中的模組,對於偏重底層技術的比如工具類 APP (或者模組),我還沒有使用 RN 嘗試過,不過想必顯然是不太適合的。總的來說,一個對於底層技術依賴不多,業務型,尤其是業務變動頻繁的應用或模組適合 RN 開發,而且一次開發,基本可以完全重用於兩個平臺,重要的是可以熱更新來應對業務邏輯更新頻繁、更新要求快、迅速修復線上 bug 等需求場景,目前看,RN 的熱更新並沒有被 Apple 封殺。 1. 無需編譯,我在第一次編譯了ipa裝好以後,就再也沒更新過app,只要更新雲端的js程式碼,reload一下,整個介面就全變了。 2. 多數佈局程式碼都是JSX,所有Native元件都是標籤化的,這對於前端程式設計師來說,降低了不少學習成本,也大大減少了程式碼量。不信你可以看看JSX編譯後的程式碼。 3. 複用React系統,也減少了一定學習和開發成本,更重要的是利用了React裡面的分層和diff機制。js層傳給Native層的是一個diff後的json,然後由Native將這個資料對映成真正的佈局檢視。 4. css-layout也是點睛之筆,前端可以繼續用熟悉的類css方式來編寫佈局,通過這個工具轉換成constrain佈局。 5. 系統只有js-objc的單向呼叫,就是把原生UI元件的方法通過javascritcore或者webview(低版本iOS)對映到js中來,整個呼叫過程是非同步的,這樣的設計令React native可以讓js執行在桌面chrome中,通過websocket連線Native code和桌面chrome,極大地方便了除錯。對其中的機制Bang的一篇文章寫得很詳細,我就不拾人牙慧了:React Native通訊機制詳解 « bang’s blog 。但這樣設計也會帶來一些問題,後面說。 6. 點按操作也被抽象成了一組元件(TouchableXXX),這種抽象方式是我在之前做類似工作中沒有想到的。facebook還列出Native為什麼和web「手感」不同的原因:實時的點按反饋和取消能力。React Native 這套相應機制設計得很完善,能像Native code那樣控制整個點按操作的所有過程。 7. Debug相當方便!修改了js以後,通過內建的nodejs watcher編譯成bundle,在模擬器裡面按cmd+r就可以看到效果。而且按cmd+d,可以開啟一個chrome視窗,所有的js都移到了chrome裡面執行,所以什麼斷點單步打呼叫棧,都不在話下。
上面的既是特點也是優點,下面說說缺點,或者應該說:「仍然遺留的問題」,在我看來,這個方案已經超越了Hybird方案。 1. 系統仍然(不得不)依賴原生元件暴露出來的元件和方法。舉兩個例子,ScrollView這個元件,在Native層是有大量事件的,scrollViewWillBeginDragging, scrollViewWillEndDragging,scrollViewDidEndDragging等等,這些事件在現有的版本都沒有暴露,基本上做不了元件聯動效果。另外,這個版本中有大量元件是iOS only的:ActivityIndicatorIOS、DatePickerIOS、NavigatorIOS、PickerIOS、SliderIOS、SwitchIOS、TabBarIOS、AlertIOS、AppStateIOS、LinkingIOS、PushNotificationIOS、StatusBarIOS、VibrationIOS,反過來看,剩餘的都是一些抽象程度極強的基本元件。這樣,使用者必須在不同的平臺下寫兩套程式碼,而且所有能力仍然強烈依賴 React native 開發人員暴露的介面。 2. 由於最外層是React,初次學習成本高,不像往常的Hybird方案,只要多學幾個JS API就可以開始幹活了。當然,React的確讓後續開發變得簡單了一些,這麼一套外來的(基於iOS)、殘缺不全的(css-layout)在React的包裝下,的確顯得不那麼面目可憎了。 另外,React Native仍然很不完善。文件還不全,我基本上是看著他的示例程式碼完成的demo,整合到已有app的文件也是今天才出來。按照官方的說法,Android版本要到半年後才釋出:Blog | React ,屆時整個系統設計可能還會有很大的變化。 ######參考 www.zhihu.com/question/27… github.com/reactnative… www.lcode.org/category/re…