公司本年度有App使命,陸陸續續用RN開闢了兩個運用。一款是觸及儀器掌握的平板項目,另一款是客戶端的App。下文談談運用RN開闢的部份認知(實在只是隨意扯一扯,沒有什麼深度)
我們合適運用RN嗎?
實在能問出這個題目的我猜只要小公司了(比方我們),由於大公司早已入坑,以至已有公司出坑了(Airbnb)。
RN的上風
- 滿足需求變動的疾速發版。原生代碼考核時候長,Hybird運轉速率又不夠快。
- 許多小公司想不招挪動開闢而開闢App,勤儉本錢。
- 跨平台,一份代碼,輕微修正部份就能夠運轉在兩個平台上。
- 營業類代碼開闢很快。
RN的弊病
- 坑多,這個坑在各個方面。RN在0.5x版本上,安卓體繫上的border襯着就有鋸齒,厥後我們不分border結果是運用圖片完成的,汗啊~
- 第三方組件不全。RN作為一個有影響力開源項目,有許多第三方組件,然則能夠毫不客氣的說,都不圓滿~ 無論是相機挪用、音頻播放照樣音訊處置懲罰,以至路由組件。許多組件須要修正源碼。由於這個組件依賴於RN0.4x,而另一個依賴於RN0.5x,這就迥殊為難。所以照樣本身原生開闢工程師供應接口,經由過程JS bridge挪用比較好。
- 對前端來講,開闢完全的App照樣須要懂原生開闢學問,對平常程序員來講Android開闢用的Java還好,然則ios的開闢言語OC簡直是魔咒。固然我們能夠面向百度和Google編程,不過這會糟蹋大批的時候且做出來並不圓滿。所以,公司想做App的話照樣最少須要一個懂Android開闢和懂IOS開闢的工程師。
- 屏幕適配,雖然RN的尺寸是相對尺寸,且供應了獵取屏幕密度等要領,然則詳細到裝備上,照樣各有差別。不過相對輕鬆的是,我開闢的平板項目只要一個尺寸,所以以至能夠運用定位來處置懲罰規劃。
開闢中的履歷
設置完RN環境,以安卓為例
在運用react-native run-android以後,實質是將Java等初始化代碼打成了一個包,後續開闢和動態更新都是經由過程讀取在經由過程敕令啟動的8081端口效勞下的js bundle完成的,所以初次湧現以下提醒
Unable to load script from assets 'index.android.bundle' ...
只須要搖一搖真機,在湧現的dialog中設置Dev setting中的host、port再reload后就一般了
因Android版本題目致使的沒法裝置
我是初次是經由過程Android 6.0開闢,厥後盤算運用Android 5.1舉行測試。毛病信息以下
com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException: Failed to install all
湧現這類狀況,網上許多說是經由過程修正gradle來舉行修正,然則一般開闢android程序時,須要測試差別的裝備。能夠直接運用adb敕令舉行裝置
adb install android/app/build/outputs/apk/app-debug.apk
緩存題目
迥殊是在運用了babel-resolver以後—,毛病信息以下
unable to resolve module ***
處理體式格局:
react-native start –reset-cache
JSX解釋語法
在運用command + /
增加解釋后,經常湧現毛病:
Cannot add a child node that doesn't have a YogaNode to a parent without measure function
處理體式格局固然是搜檢本身的JSX代碼是不是解釋寫的不對。
搖一搖題目的處理(Android)
在我們運用了Mobx Redux
等狀況治理時,熱更新不會更新這些代碼,而頻仍搖一搖實在是太累了。此時能夠運用
adb shell input keyevent 82
此時相當於虛擬了一個搖一搖事宜。
長途調試(root裝備)
當我們的開闢環境可能有多種裝備且不輕易插USB得話,能夠舉行Adb長途調試。要領以下:
1. 安卓端:起首裝置安卓終端模擬器
su
setprop service.adb.tcp.port 5555
stop adbd
start adbd
2. 開闢端:
adb connect ANDROID_HOST
adb install ***.apk
須要喚出設置頁面的話,用上面的搖一搖題目的處理方案
JS挪用Android代碼
以經由過程js獵取原生Android序列號為例,此處代碼會比官方文檔全。其他的能夠參考官方文檔
- 在與android的MainActivity同級目次下新建一個SerialNumberModule.java文件,內容以下:
public class SerialNumberModule extends ReactContextBaseJavaModule{
@Override
public String getName() {
return "SerialNumber";
}
public SerialNumberModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@ReactMethod
public void getSerialNumber (Callback successCallback, Callback errorCallback) {
String SerialNumber = android.os.Build.SERIAL;
try {
successCallback.invoke(SerialNumber);
} catch (IllegalViewOperationException e) {
errorCallback.invoke(e.getMessage());
}
}
}
- 在新建一個SerialNumberPackage.java文件,用來增加模塊,代碼以下:
public class SerialNumberPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new SerialNumberModule(reactContext));
return modules;
}
}
- 在本目次的MainApplication.java中重寫的getPackages中new此模塊,代碼:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new SerialNumberPackage()
);
}
- js端挪用,以rn的進口App.js為例
import { NativeModules } from 'react-native'
*******
在組件內:
componentWillMount () {
NativeModules.SerialNumber.getSerialNumber(success => {
console.log('success', success)
}, err => {
console.log('err', err)
})
}
刊行IOS包
能夠在項目根目次下實行
1. react-native bundle --entry-file index.js --bundle-output ./ios/bundle/index.ios.jsbundle --platform ios --assets-dest ./ios/bundle --dev false
2. 修正AppDelegate.m文件,將
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
解釋掉,並增加
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"index.ios" withExtension:@"jsbundle"];
3. 將打好的文件在ios目次下的bundle目次里的兩個文件和一個文件夾拖拽到Xcode的項目響應名字的目次下
4. 插上真機,在Xcode的目的上挑選真機,點擊Xcode標題欄的product --> archive即可
先上結論,個人認為這類開闢形式遲早會完畢,第三方強行兼容裝備老是不可的。類比黑莓兼容Android。個人照樣信WEB, 信W3C。踩坑還在舉行,上述只是一點開闢履歷。大神輕噴,同行人迎接一同議論。