javascript - React Native 视频和图像播放器内存泄漏
问题描述
我正在尝试在 React Native 中实现视频和图像播放器,但应用程序在一段时间后崩溃。我认为某处存在内存泄漏,我不知道为什么。
我有一系列视频和图像,每个图像都有时间显示。
当我使用 Android Profiler 分析应用程序时(因为该应用程序仅适用于 Android),每次更改索引时,内存使用量都会增加。
该应用程序将在短时间内消耗超过 800 MB。
有没有办法进行清理或其他什么?
const PresentationScreen24h = (props) => {
const {displayBanner, playable_files, isInternetAccessible, player24hSchedule } = props;
const [canPlaylistStart, setCanPlaylistStart] = useState(false);
const [currentIndex, setCurrentIndex] = useState(0);
const [currentPlayingItem , setCurrentPlayingItem] = useState();
const playableSources = useRef([]);
const timeoutID = useRef();
useEffect(()=>{
fillPlayableSource();
console.log("PRESENTATION SCREEN 24h MOUNTED")
StatusBar.setHidden(true)
return () => {
console.log('PRESENTATION SCREEN 24h UNMOUNTED -----')
clearTimeout(timeoutID?.current);
}
},[])
useEffect(() => {
if(cleanupBT && false){
CleanupInBackgroundThread();
setCleanupBT(false)
}
}, [cleanupBT])
const handleOnVideoEnd = () =>{
increaseIndex();
}
const increaseIndex =() =>{
if(playableSources.current.length == 0 || !currentPlayingItem ) return;
if(timeoutID.current) clearTimeout(timeoutID.current)
const playedTime = moment(new Date()).format('YYYY_MM_DD_HH_mm_ss').toString();
if(currentPlayingItem?.mime != "webpage"){
if (currentPlayingItem?.fisier && currentPlayingItem?.fisier?.length > 2 && playedTime && playedTime?.length == 19 )
acknowledgePlayOfFile(currentPlayingItem?.fisier, playedTime, currentPlayingItem?.pofp_server_playNotif);
}
else{
acknowledgePlayOfFile(currentPlayingItem.website_id, playedTime, currentPlayingItem?.pofp_server_playNotif)
}
setCurrentIndex(c => c + 1 < playableSources.current.length ? c + 1 : 0)
}
const fillPlayableSource = () => {
if(!player24hSchedule.length || player24hSchedule.length == 0 ) return;
playableSources.current = player24hSchedule;
setCanPlaylistStart(true)
};
useEffect(()=>{
if(playableSources.current.length > 0)
setCanPlaylistStart(true);
},[playableSources])
useEffect(() => {
if(playableSources.current.length == 0) return
if(canPlaylistStart)
setCurrentPlayingItem(playableSources.current[currentIndex]);
}, [canPlaylistStart])
useEffect(() => {
if(playableSources.current.length == 0) return;
{/* SKIP IF THE NEXT ITEM IS WEBSITE AND IS OFFLINE MODE*/}
if( !isInternetAccessible && playableSources.current[currentIndex].mime == 'webpage')
setCurrentIndex(c => c + 1 < playableSources.current.length ? c + 1 : 0)
else
setCurrentPlayingItem(playableSources.current[currentIndex]);
{/* CHECK IF IS NEW DAY AT EVERY 5TH ITEM */}
if(currentIndex % 5 ==0 )
checkIfIsNewDay(moment(playableSources.current[0].start).date())
}, [currentIndex])
useEffect(() => {
if (!currentPlayingItem || playableSources.length == 0) return;
if (currentPlayingItem)
if (currentPlayingItem?.mime != 'video/mp4') {
let time = moment(currentPlayingItem.end, 'YYYY-MM-DD HH:mm:ss') - moment();
if (time < 0 || time / 1000 - currentPlayingItem.durata > 15)
getCurrentItem(playableSources.current).then(index => setCurrentIndex(index));
else {
timeoutID.current = setTimeout(() => {
increaseIndex()
}, time)
}
}
}, [currentPlayingItem])
useEffect(() => {
if(player24hSchedule && player24hSchedule.length > 0 )
fillPlayableSource();
}, [player24hSchedule])
return (
<View style={styles.container }>
{!currentPlayingItem ?
<Text style={styles.text}> NO available item </Text>
:(
currentPlayingItem.mime =='webpage' ?
<View style={{flex:1, backgroundColor:"#000"}}>
<WebViewComponent visible={true} url={currentPlayingItem.fisier} />
</View>
:
currentPlayingItem.mime =='video/mp4' ? <VideoView item={currentPlayingItem} onVideoEnd={()=>handleOnVideoEnd()} /> :
currentPlayingItem.mime =='image/jpg' ? <ImageView uri={currentPlayingItem.url} /> :
<Text style={styles.text}> INVALID TYPE OF DATA </Text>
)
}
{displayBanner && <BannerMessage />}
</View>
)
}
const ImageView = ({uri}) => {
return <View style={styles.blackContainer}>
<Image source={{uri: uri}} resizeMode="contain" style={styles.image} />
</View>
}
const VideoView = ({item, onVideoEnd}) =>{
return (
<View style={styles.blackContainer}>
<Video
source={{ uri: item.url }}
onBuffer={() => { console.log("BUFFERING VIDEO");}}
onError={() => {console.log('ERROR VIDEO')}}
// onLoad={()=>{console.log("onLoad")}}
// onLoadStart={()=>{console.log("onLoadStart") }}
// onReadyForDisplay={()=>{console.log("onReadyForDisplay");}}
onEnd={onVideoEnd}
resizeMode={"contain"}
style={styles.video}
poster={item.videoCover? item.videoCover : null}
posterResizeMode={'contain'}
hideShutterView={true}
/>
</View>
);
}
解决方案
推荐阅读
- node.js - axios请求加载资源失败:服务器响应状态为404(未找到)
- angular - 我在 Angular Template Driven Form 中对这个路由守卫做错了什么?
- azure-pipelines - 并行运行 1 个以上的 Azure Devops Pipeline
- clojurescript - 从引导的 clojure REPL 连接到浏览器 REPL 需要永远在 clojurescript
- php - HTML 下载属性不适用于 CDN 打开
- react-native - 如何创建像 pinterest 这样的长按菜单?[反应原生]
- javascript - 对象字面量中的自引用
- sql - 将字符串拆分为多列,不带分隔符 bigquery
- javascript - 如何连接后端开发服务器和前端开发服务器
- xpath - 从 Ranorex Selocity Chrome 扩展粘贴复制的 Xpath 不起作用