环境
os: mac 10.13
react-native-cli: 2.0.1
react-native: 0.61.5
nodejs:v13.1.0
模拟器:网易mumu模拟器
- 新建的项目未设置Android SDK路径,运行
react-native run-android
模拟器无法打开app
info Running jetifier to migrate libraries to AndroidX. You can disable it using "--no-jetifier" flag.
Jetifier found 864 file(s) to forward-jetify. Using 6 workers...
info Starting JS server...
* daemon not running; starting now at tcp:5037
* daemon started successfully
info Installing the app...
Starting a Gradle Daemon (subsequent builds will be faster)
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':app'.
> SDK location not found. Define location with an ANDROID_SDK_ROOT environment variable or by setting the sdk.dir path in your project's local properties file at '/Volumes/mnt/code/myApp/android/local.properties'.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 7s
error Failed to install the app. Make sure you have the Android development environment set up: https://facebook.github.io/react-native/docs/getting-started.html#android-development-environment. Run CLI with --verbose flag for more details.
Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':app'.
> SDK location not found. Define location with an ANDROID_SDK_ROOT environment variable or by setting the sdk.dir path in your project's local properties file at '/Volumes/mnt/code/myApp/android/local.properties'.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 7s
at checkExecSyncError (child_process.js:603:11)
at execFileSync (child_process.js:621:15)
at runOnAllDevices (/Volumes/mnt/code/myApp/node_modules/@react-native-community/cli-platform-android/build/commands/runAndroid/runOnAllDevices.js:94:39)
at buildAndRun (/Volumes/mnt/code/myApp/node_modules/@react-native-community/cli-platform-android/build/commands/runAndroid/index.js:158:41)
at /Volumes/mnt/code/myApp/node_modules/@react-native-community/cli-platform-android/build/commands/runAndroid/index.js:125:12
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async Command.handleAction (/Volumes/mnt/code/myApp/node_modules/@react-native-community/cli/build/index.js:164:9)
在项目根目录下(package.json所在的目录),android/
下新建local.properties
文件,配置如下内容:
sdk.dir = /Users/zlbao/Library/Android/sdk #mac安装AndroidStudio后默认会自动从google下载sdk(需要梯子),也可以自己下载后配置环境变量
- 安装pod install卡住不动
我也碰到这种问题,排查过后,是由于网络原因, 无法下载cocoapods导致的。 怎么办呢?咱们可以换一个源头, 类似于npm中的cnpm 。
第一步: 开始安装Cocoapods
sudo gem install cocoapods//或者brew install cocoapods
第二步:
切换 镜像cocoapods镜像: git clone https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git master
第三部:
初始化你的项目: react-native init MyApp
项目初始化还是会卡住。
第四部 ,按照提示 执行: cd ./MyApp/ios && pod install
在第三步之后 ./ios/Podfile 顶部添加一行: source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
- 安装mumu虚拟机后adb devices不显示(windows)
//如果你的android环境能够直接访问 adb 的相关指令.只需要把mumu模拟器打开 然后打开cmd -> 输入
adb connect 127.0.0.1:7555 //win就能直接连上mumu模拟器了
adb kill-server && adb server && adb shell//mac
//如果不能运行adb,那么说明Android sdk没有安装或者环境变量没有配置
image.png
-
安装intel haxm error失败(错误),导致无法使用AndroidStudio的虚拟机
a. 将VT、虚拟化关闭(bios)
b. 安装intel haxm,如果安装成功,那么再次重新开启上面关闭的功能
c. hyper-v始终保持关闭状态 -
运行错误react-native start
将nodejs降级到v12.8.0,v12.13出现错误 -
react-native-video 不能播放 m3u8 文件
插件:
react-native-video
react-native-video-controls
react-native-vector-icons
//controls依赖
settings.gradle
rootProject.name = 'myApp3'
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
include ':react-native-video'
project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android-exoplayer')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
//特别注意include ':react-native-video'
project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android-exoplayer'),最后是android-exoplayer,默认link是android
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React from 'react';
import {
SafeAreaView,
StyleSheet,
ScrollView,
View,
Text,
StatusBar,
Dimensions,
TextInput,
TouchableOpacity, Image, Touchable, TouchableWithoutFeedback,
} from 'react-native';
import {
Header,
LearnMoreLinks,
Colors,
DebugInstructions,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
import Video from 'react-native-video';//插件
import VideoPlayer from 'react-native-video-controls';//插件
const screenWidth = Dimensions.get('window').width;
const navs = [
'首页',
'首页1',
];
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
navIndex: 0,
countDownStart: false,
countDown: 60,
rate: 1,
volume: 1,
muted: false,
resizeMode: 'contain',
duration: 0.0,
currentTime: 0.0,
paused: true,
};
video: Video;
}
render() {
const flexCompleted = this.getCurrentTimePercentage() * 100;
const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100;
var Arr = navs.map((item, index) => {
// console.log('item:', item, 'index:', index);
return (
<TouchableWithoutFeedback key={index} onPress={() => this.handleClickNavItem(item, index)}>
<View style={styles.navitem}>
<Text style={index === this.state.navIndex ? styles.navitemActive : ''}>首页</Text>
</View>
</TouchableWithoutFeedback>
);
});
let url = 'http://xxx.mp4';
// url = 'http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8';//ok
return (
<>
<StatusBar barStyle="dark-content"/>
<SafeAreaView>
<ScrollView>
{false ? (
{/**Video安卓不带控制条等,VideoPlayer带控制条**/}
<Video
//source={{uri: url}} // Can be a URL or a local file.
// source={require('./assets/videoplayback.mp4')}//check
// source={{uri:url}}//Check
source={{
uri: url, type: 'm3u8', headers: {
Referer: 'https://www.google.com/',
},
}}
ref={(ref: Video) => {
this.video = ref;
}} // Store reference
onBuffer={this.onBuffer} // Callback when remote video is buffering
onError={this.videoError} // Callback when video cannot be loaded
style={styles.backgroundVideo}
rate={1}
resizeMode={'cover'}/>
) : (
<VideoPlayer
//source={require('./assets/videoplayback.mp4')}
source={{
uri: url, type: 'm3u8', headers: {
Referer: 'https://www.google.com/',
},
}}///不能用
onBuffer={this.onBuffer} // Callback when remote video is buffering
onError={this.videoError} // Callback when video cannot be loaded
style={styles.backgroundVideo}
rate={1}
resizeMode={'cover'}/>
)}
<Text>test</Text>
</ScrollView>
</SafeAreaView>
</>
);
}
onBuffer = () => {
alert('onBuffer');
};
videoError = (e) => {
console.log('e', e);
alert(e);
};
handleClickNavItem = (ev, index) => {
console.log('ev:', ev);
console.log('index:', index);
this.setState({
navIndex: index,
});
};
handleGetSmsCode = () => {
// alert('get code')
if (this.state.countDownStart === true) {
console.log('已开始');
return;
}
this.setState({
countDownStart: true,
countDown: this.state.countDown - 1,
});
let inter1 = setInterval(() => {
if (this.state.countDown > 0) {
this.setState({
countDownStart: true,
countDown: this.state.countDown - 1,
});
} else {
clearInterval(inter1);
this.setState({
countDown: 60,
countDownStart: false,
});
}
}, 1000);
};
onLoad = (data) => {
this.setState({duration: data.duration});
};
onProgress = (data) => {
this.setState({currentTime: data.currentTime});
};
onEnd = () => {
this.setState({paused: true});
this.video.seek(0);
};
onAudioBecomingNoisy = () => {
this.setState({paused: true});
};
onAudioFocusChanged = (event: { hasAudioFocus: boolean }) => {
this.setState({paused: !event.hasAudioFocus});
};
getCurrentTimePercentage() {
if (this.state.currentTime > 0) {
return parseFloat(this.state.currentTime) / parseFloat(this.state.duration);
}
return 0;
};
renderRateControl(rate) {
const isSelected = (this.state.rate === rate);
return (
<TouchableOpacity onPress={() => {
this.setState({rate});
}}>
<Text style={[styles.controlOption, {fontWeight: isSelected ? 'bold' : 'normal'}]}>
{rate}x
</Text>
</TouchableOpacity>
);
}
renderResizeModeControl(resizeMode) {
const isSelected = (this.state.resizeMode === resizeMode);
return (
<TouchableOpacity onPress={() => {
this.setState({resizeMode});
}}>
<Text style={[styles.controlOption, {fontWeight: isSelected ? 'bold' : 'normal'}]}>
{resizeMode}
</Text>
</TouchableOpacity>
);
}
renderVolumeControl(volume) {
const isSelected = (this.state.volume === volume);
return (
<TouchableOpacity onPress={() => {
this.setState({volume});
}}>
<Text style={[styles.controlOption, {fontWeight: isSelected ? 'bold' : 'normal'}]}>
{volume * 100}%
</Text>
</TouchableOpacity>
);
}
};
const styles = StyleSheet.create({
backgroundVideo: {
// position: 'absolute',
// top: 0,
// left: 0,
// bottom: 0,
// right: 0,
// backgroundColor:'red',
borderWidth: 1,
height: 200,
minHeight: 200,
width: 300,
minWidth: 300,
},
//---------------------
yknav: {
height: 27.59,
marginTop: 9,
marginBottom: 9,
},
headernav: {
paddingLeft: 15,
flex: 0,
flexDirection: 'row',
justifyContent: 'space-around',
},
navitem: {
paddingRight: 33.12,
},
navitemActive: {
color: '#24a5ff',
},
image: {
width: 20, height: 20,
marginRight: 10,
},
//-------------------
loginForm: {
/// 414 / 331.22 比例 1:0.8
width: screenWidth * 0.8,
},
formItem: {
marginBottom: 10,
width: '100%',
},
fmMobile: {
paddingHorizontal: 15,
borderColor: '#e9e9e9',
borderWidth: 1,
borderRadius: 44,
width: '100%',
height: 42,
lineHeight: 42,
paddingTop: 10,//android
},
fmSMSCode: {
paddingHorizontal: 15,
borderColor: '#e9e9e9',
borderWidth: 1,
borderRadius: 44,
width: '100%',
height: 42,
lineHeight: 42,
paddingTop: 10,//android
flex: 0,
flexDirection: 'row',
justifyContent: 'center',
},
sendBtn: {
position: 'absolute',
right: 15,
height: 42,
},
sendBtnLink: {
color: '#08c',
height: 42,
lineHeight: 42,
},
fmBtn: {
backgroundColor: '#2692ff',
borderRadius: 44,
width: '100%',
height: 42,
},
fmBtnLogin: {
textAlign: 'center',
lineHeight: 42,
height: 42,
color: '#fff',
},
//-------------------
scrollView: {
backgroundColor: Colors.lighter,
},
engine: {
position: 'absolute',
right: 0,
},
body: {
backgroundColor: Colors.white,
},
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
color: Colors.black,
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
color: Colors.dark,
},
highlight: {
fontWeight: '700',
},
footer: {
color: Colors.dark,
fontSize: 12,
fontWeight: '600',
padding: 4,
paddingRight: 12,
textAlign: 'right',
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black',
},
fullScreen: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
controls: {
backgroundColor: 'transparent',
borderRadius: 5,
position: 'absolute',
bottom: 20,
left: 20,
right: 20,
},
progress: {
flex: 1,
flexDirection: 'row',
borderRadius: 3,
overflow: 'hidden',
},
innerProgressCompleted: {
height: 20,
backgroundColor: '#cccccc',
},
innerProgressRemaining: {
height: 20,
backgroundColor: '#2C2C2C',
},
generalControls: {
flex: 1,
flexDirection: 'row',
borderRadius: 4,
overflow: 'hidden',
paddingBottom: 10,
},
rateControl: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
},
volumeControl: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
},
resizeModeControl: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
controlOption: {
alignSelf: 'center',
fontSize: 11,
color: 'white',
paddingLeft: 2,
paddingRight: 2,
lineHeight: 12,
},
});
一开始测试本地mp4,网络mp4都可以播放,唯独不能播放m3u8文件,安卓5.0的模拟器花屏,需要使用高等级的或者使用mumu模拟器。以为是插件不支持,浪费了半天时间,发现是m3u8文件的问题,网络上的资源好多都不能直接播放(貌似和跨域或者认证有关),需要收集可以使用的m3u8才能播放,
花屏http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8
这个视频是可以播放的
网友评论