<h5>項目背景</h5>
本身
現有的選型框架
- 國產阿里傳說中的weex.
https://github.com/alibaba/weex
Start很多,覺得很牛逼,但是ISSUE上面問題也比較多。后面向阿里的同學確認,問他們用的多么。給出的答案是,不敢用,只有天貓與淘寶兩個部門使用。自己領會。文檔,也覺得不是特別的全。經測試,還是需要在兼容性方面做改進。
- FB的React Native .、
http://facebook.github.io/react-native/
Paste_Image.png
個人感覺 ,文檔那是相當的全啊。基本上是按照流程來,就應該是沒有問題了。
整個結構思路
RN 這套框架讓 JS開發者可以大部分使用JS代碼就可以構建一個跨平臺APP。 Facebook官方說法是learn once, run everywhere, 即在Android 、 IOS、 Browser各個平臺,程序畫UI和寫邏輯的方式都大致相同。因為JS 可以動態加載,從而理論上可以做到write once, run everywhere, 當然要做額外的適配處理。如圖:
RN需要一個JS的運行環境, 在IOS上直接使用內置的javascriptcore, 在Android 則使用webkit.org官方開源的jsc.so。 此外還集成了其他開源組件,如fresco圖片組件,okhttp網絡組件等。 RN 會把應用的JS代碼(包括依賴的framework)編譯成一個js文件(一般命名為index.android.bundle), , RN的整體框架目標就是為了解釋運行這個js 腳本文件,如果是js 擴展的API, 則直接通過bridge調用native方法; 如果是UI界面, 則映射到virtual DOM這個虛擬的JS[數據結構](http://lib.csdn.net/base/datastructure)中,通過bridge 傳遞到native , 然后根據數據屬性設置各個對應的真實native的View。 bridge是一種JS 和 [Java](http://lib.csdn.net/base/javase)代碼通信的機制, 用bridge函數傳入對方module 和 method即可得到異步回調的結果。
對于JS開發者來說, 畫UI只需要畫到virtual DOM 中,不需要特別關心具體的平臺, 還是原來的單線程開發,還是原來HTML 組裝UI(JSX),還是原來的樣式模型(部分兼容 )。RN的界面處理除了實現View 增刪改查的接口之外,還自定義一套樣式表達CSSLayout,這套CSSLayout也是跨平臺實現。 RN 擁有畫UI的跨平臺能力,主要是加入Virtual DOM編程模型,該方法一方面可以照顧到JS開發者在html DOM的部分傳承, 讓JS 開發者可以用類似DOM編程模型就可以開發原生APP , 另一方面則可以讓Virtual DOM適配實現到各個平臺,實現跨平臺的能力,并且為未來增加更多的想象空間, 比如react-cavas, react-openGL。而實際上react-native也是從react-js演變而來。
對于 Android 開發者來說, RN是一個普通的安卓程序加上一堆事件響應, 事件來源主要是JS的命令。主要有二個線程,UI main thread, JS thread。 UI thread創建一個APP的事件循環后,就掛在looper等待事件 , 事件驅動各自的對象執行命令。 JS thread 運行的腳本相當于底層數據采集器, 不斷上傳數據,轉化成UI 事件, 通過bridge轉發到UI thread, 從而改變真實的View。 后面再深一層發現, UI main thread 跟 JS thread更像是CS 模型,JS thread更像服務端, UI main thread是客戶端, UI main thread 不斷詢問JS thread并且請求數據,如果數據有變,則更新UI界面。
集成過程(在現有的應用中加入React 實現熱更新代碼)
React Native is great when you are starting a new mobile app from scratch. However, it also works well for adding a single view or user flow to existing native applications. With a few steps, you can add new React Native based features, screens, views, etc.
The keys to integrating React Native components into your Android application are to:
1)安裝React ,明確你需要使用它的什么組件。
2)使用react-native 在你現有的安卓項目的主目錄下面,創建node_modules/文件
3)開始用js創建你要的頁面。
4)配置現有的項目,集成React 的相關依賴包。
5)使用Reactive 的文件
6)編譯相關的項目文件 。
7)添加自定義的控件
8)Debug的介紹。
9)應用打包
10)使用CodePush熱更新
注意事項
1)項目配置完后,有可能在模擬機上面,跑著的是正常的。但是呢,有的機器就跑不起來,請配置好相關的so文件 。
2)項目是正常的啟動起來了,結果呢,npm start 服務一關,測試機上面自動的crash,正式版可是沒有npm服務啊,需要將相關的bundle文件打包到手機項目工程中,這樣啟動的話,就會依賴于apk中的assets文件 。生成bundle命令》
react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output [your-project-path]/app/src/main/assets/index.android.bundle --assets-dest [your-app-project-path]/app/src/main/res
執行完成后,再進行debug這時,將從assets上面加載相關文件了。不需要使用npm start.
3)Code Push的使用(記得版本號要與你的應用的version name是一樣的哦),將生成的bundle 文件推到code push 平臺
code-push release demo-android-dev ./bundles/index.android.bundle 1.5.1 --deploymentName Production --description "1.5.1" --mandatory true
code-push release demo-android-dev ./bundles/index.android.bundle 1.4.9 --description "ok 1.4.10+1" --mandatory true
- js文件的更新代碼如下:
'use strict';
import React from 'react';
import codePush from 'react-native-code-push';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';
let codePushOptions = { checkFrequency: codePush.CheckFrequency.MANUAL };
class HelloWorld extends React.Component {
onButtonPress() {
codePush.sync({
updateDialog: true,
installMode: codePush.InstallMode.IMMEDIATE
});
}
componentDidMount(){
//codePush.sync();
}
render() {
return (
<View style={styles.container}>
<Text style={styles.hello}>Code Push--test push 1.4.9++</Text>
<View>
<TouchableOpacity onPress={this.onButtonPress}>
<Text>Check for updates</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
hello: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
//HelloWorld = codePush(HelloWorld);
HelloWorld = codePush(codePushOptions)(HelloWorld);
AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
一些思考