首页 > 解决方案 > 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>
      
    );
}

标签: javascriptreactjsreact-nativeperformancememory-leaks

解决方案


推荐阅读