React?Native?for?Android?Windows環境搭建
來自: http://www.alloyteam.com/2016/03/react-native-for-android-windows/
環境搭建
1.準備工作
AndroidStudio 安卓開發IDE 推薦下載含SDK tools版
JDK for Windows Java軟件開發工具包
Nodejs nodejs環境
2.安裝ReactNative步驟
1) 使用npm安裝ReactNative
在cmd命令工具中執行以下命令,注意并非 install react-native,裝了react-native在后面init項目的時候會報錯,需要卸掉再重裝。
npm install -g react-native-cli
2)可能遇到的問題:
報錯:npm-install-save-react-native-failed
解決辦法:升級nodejs及npm版本
報錯:'xxx’不是內部或外部命令
解決辦法:設置對應命令為環境變量或安裝對應的命令工具
3.安卓環境搭建
1)JDK安裝
運行已下載的jdk-xxxx-windows-x64.exe進行安裝,如本地已有JDK可跳過本條。
2)AndroidStudio安裝
運行已下載的android-studio-bundle-xxx-windows.exe進行安裝
安裝Android Studio完畢后,需要檢查Android SDK是否齊全,對應需要的SDK如下所示:
ReactNative開發調試體驗
1.HelloWorld程序
在AndroidStudio中創建一個Android HelloWorld程序:
2.調試手機啟用開發者模式并連接USB選擇允許調試
開啟開發者模式方式以小米機型為例參考 小米手機示例 。
3.運行HelloWorld
點擊運行并在列表中選擇調試的手機,確定后手機會自動安裝我們的HelloWorld程序:
保持程序運行狀態,我們可以在AndroidStudio控制臺上查看程序輸出的log日志及CPU/內存等占用情況。
4.HelloAndroid程序
使用命令行工具運行命令:
react-native init HelloAndroid
完成目錄結構:
在AndroidStudio上打開HelloAndroid/android目錄,等待gradle構建完畢后運行HelloAndroid程序,可以看到以下ReactNatibe經典報錯UI,這是因為我們還未連接上react-native的編譯bundle文件而導致出現的錯誤頁面。
下面我們來運行Android ReactNative構建命令:
react-native start
注意這里不是使用run-android,run-android適用于直接在機器上運行調試app。
當構建完畢,在瀏覽器中訪問http://localhost:8081/index.android.bundle?platform=android可以看到我們編譯好的android bundle文件。
調試方式
1.配置host方式:
搖晃手機調出app debug菜單選項 ->選擇Dev Settings-> 選擇Debug server host & port for device -> 填寫PC局域網IP及端口(命令行輸入ipconfig可查看本機ip)
如上圖,填寫192.168.1.100:8081即可,回退到主界面,再次搖晃手機調出app debug 菜單選項 ->選擇 Reload JS,此時可以看到ReactNative的應用首頁:
2.Android5.0以上版本命令方式:
打開Android SDK目錄 xxx\Android\sdk\platform-tools。在當前文件路徑呼出命令行,輸入:
adb reverse tcp:8081 tcp:8081
點擊Reload JS 即可成功拉取ReactNative bundle。
注意:adb命令可以添加到windows全局變量中,這樣無需在xxx\Android\sdk\platform-tools目錄下執行adb命令,可以在AndroidStudio的Terminal命令行工具下使用
3.模擬器調試方式
安卓模擬器在win平臺上性能表現不是很好,我們可以安裝 英特爾? 硬件加速執行管理器 來進行一些性能上的提升(需要Intel的CPU),安裝完畢后在AndroidStudiao的菜單點擊打開虛擬設備管理器,選擇創建一個Android虛擬設備(需求不同的Android版本需要下載對應的SDK Tool)并啟動。
當Android虛擬設備啟動成功后,運行HelloAndroid 應用app,選擇已啟動的虛擬設備即可在虛擬設備上打開我們的HelloAndroid。
編寫一個示例RNA輪播
index.android.js 入口函數:
importDemofrom './android_src/Demo';
class HelloAndroid extends Component {
render() {
return (
<Viewstyle={styles.container}>
<Demo></Demo>
</View>
);
}
}
首頁Demo.js:
/**
* 首頁
*/
importReact, {Component, ScrollView} from 'react-native';
importSliderfrom './Slider';
class Demo extends Component {
constructor(props) {
super(props);
this.state = {
banner: [
{banner_url:'http://ossweb-img.qq.com/images/lol/web201310/skin/big80006.jpg'},
{banner_url:'http://i12.tietuku.com/707b3565e98e1398s.jpg'},
{banner_url:'http://imga1.pic21.com/bizhi/140226/07916/s04.jpg'}]
};
}
render() {
return (
<ScrollViewstyle={{flex:1,marginBottom:50}}>
<Sliderdata={this.state.banner}/>
</ScrollView>);
}
}
module.exports = Demo;
輪播組件函數Slider.js:
/**
* 輪播組件
*/
importReact, {
Image,
Text,
View,
ViewPagerAndroid,
StyleSheet,
Dimensions,
TouchableOpacity
} from 'react-native';
var Slider = React.createClass({
getInitialState() {
return {
currentPage: 0,
viewWidth: 0,
renderStatus: false
};
},
render(){
// 獲取待渲染的圖片數據
var imgsRenderData = this.getImgsRenderData(this.props.data);
// 將圖片列表數據逐個映射到JSX中
var imgs = imgsRenderData.map((banner, i) => {
console.log(banner.banner_url);
return (
<Viewstyle={{flexDirection: 'column'}} key={i}>
<TouchableOpacitydelayPressIn={0} style={{flex:1}}>
<Image key={i} source={{uri:banner.banner_url}} style={{flex:1}}/>
</TouchableOpacity>
</View>
);
});
// var dots = this.renderDots();
return (
<View>
<ViewPagerAndroid
style={{flex:1,height: 160}}
initialPage={1}
ref={viewPager => { this.viewPager = viewPager; }}
onPageScroll={this.onPageScroll}
onPageSelected ={this.onPageSelected}>
{imgs}
</ViewPagerAndroid>
</View>
);
},
getImgsRenderData(data) {
// 判斷當前的輪播序號,重新對圖片順序進行組裝
var imgsRender = [];
var imgsLent = data.length;
var indexNum = this.state.currentPage;
// 這里的代碼有點亂,還有優化空間
if (imgsLent > 1 && indexNum === 0) {
imgsRender.push(data[imgsLent - 1]);
} else {
imgsRender.push(data[indexNum - 1]);
}
imgsRender.push(data[indexNum]);
if (imgsLent > 1 && indexNum === imgsLent - 1) {
imgsRender.push(data[imgsLent - 1]);
} else {
imgsRender.push(data[indexNum + 1]);
}
return imgsRender;
},
onPageSelected(event){
// 當前分頁被選中
var lastPage = this.state.currentPage;
var selectPage = event.nativeEvent.position;
var currentPage = lastPage + selectPage - 1;
var imgsLent = this.props.data.length;
if(currentPage === -1){
currentPage = imgsLent - 1;
}else if(currentPage === imgsLent){
currentPage = 0;
}
this.setState({
currentPage: currentPage
});
this.viewPager.setPageWithoutAnimation(1);
}
});
var styles = StyleSheet.create({
tab: {
alignItems: 'stretch',
},
tabs: {
flexDirection: 'row',
alignItems: 'stretch',
justifyContent: 'center',
}
});
module.exports = Slider;
運行結果:
演示動畫(因篇幅關系,輪播序號圓點的代碼不包含在以上代碼中):
搭建過程遇到的問題
1.比較常見的MSBuild錯誤
這個錯誤出現的頻率比較高,一般是安裝與window環境相關的node包時可能會出現,比如node-gyp會報這個錯,報錯形式為:MSBUILD:error MSB3248 .. .
解決方式:
VisualStudio2013Express 微軟的IDE(如本地環境有或更高版本則無須)
Win7 SDKs 7.1 windows開發工具包(如本地環境有則無須)
Win7:安裝VisualStadio2013 + Win7 SDKs 7.1
如Win7 SDKs 7.1安裝失敗,可以卸裝電腦上的
Visual c++ 2010 x86 redistributable及Visual c++ 2010 x64 redistributable再重 試
Win8: 安裝VisualStadio2013
2.folly::toJson兼容錯誤
在目前版本的RNA上遇到了這個錯誤,
經過了一番調試及查找答案,發現 是alignItems: 'center'這個樣式引起 的,具體參見 issue ,把alignItems 修改為 alignItems: 'stretch'即可
</div>