android listview 内存溢出



  • 我的listview有1000多行数据。在滑动过程中内存增长很快。当滑动到600多行,发生内存溢出。谁知道是怎么回事啊。
    class reactNative extends React.Component {
    constructor(props) {
    super(props);
    ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {dataSource: ds.cloneWithRows(dataSet)};
    this._listDataChanged = this._listDataChanged.bind(this);
    this._scrollToPoisition = this._scrollToPoisition.bind(this);
    this._reachEnd = this._reachEnd.bind(this);
    }

    dataCallback(data){
    	dataSet = JSON.parse(data);
    //	pageIndex = 0;
    //	dataSet = newData.slice(pageIndex*pageSize, pageIndex*pageSize+pageSize);
    	this.setState( {dataSource: this.state.dataSource.cloneWithRows(dataSet)});
    }
    
    
    componentWillMount(){
    	DeviceEventEmitter.addListener(
                       'achievement_data_changed',
                       this._listDataChanged);
    	DeviceEventEmitter.addListener(
                       'scroll_to_position',
                       this._scrollToPoisition);
    }
    
    _scrollToPoisition(e:Event){
    	var posY = e.position*PixelRatio.getPixelSizeForLayoutSize(80);
    	
    	this._listView.scrollTo({x:0, y:posY, animated:false});
    	
    }
    
    _listDataChanged(e:Event){
    	dataControl.getData(this.dataCallback.bind(this));
    }
    _reachEnd(){
    	pageIndex++;
    	var newPage = newData.slice(pageIndex*pageSize, pageIndex*pageSize+pageSize);
    	dataSet = dataSet.concat(newPage);
    	//alert("dataset length:"+dataSet.length);
    	if(pageIndex>0 && pageIndex%3===0){
    		dataSet.splice(0, pageSize);
    	}
    	
    	alert("dataset length:"+dataSet.length);
    	this.setState( {dataSource: ds.cloneWithRows(dataSet)});
    }
    
    _renderRow(rowData: Object,sectionID: number, rowID: number) {
    
    	var roundMask = 'rn_bg_photos_normal';
    	var arrowBgHead = 'bg_place_normal_head';
    	var arrowBgCenter = 'bg_place_normal_center';
    	var arrowBgTail = 'bg_place_normal_tail';
    	var retialOpacity = 0;
    	var lltubStyle = styles.lltubShow;
    	var imgSource = 'rank_normal';
    	var rowBg = '#d9d6d7';
    	var indexTextColor = '#f06100';
    	var index = rowID*1+1;
    	if(rowID == 0){
    		imgSource='rank_one';
    		rowBg='#fb684b';
    		indexTextColor = '#bc4f00';
    		arrowBgHead = 'bg_place_one_head';
    		arrowBgCenter = 'bg_place_one_center';
    		arrowBgTail = 'bg_place_one_tail';
    		roundMask = 'rn_bg_photos_one';
    	}else if(rowID == 1){
    		imgSource='rank_two';
    		rowBg='#fb684b';
    		indexTextColor = '#666666';
    		arrowBgHead = 'bg_place_two_head';
    		arrowBgCenter = 'bg_place_two_center';
    		arrowBgTail = 'bg_place_two_tail';
    		roundMask = 'rn_bg_photos_two';
    	}else if(rowID == 2){
    		imgSource='rank_three';
    		rowBg='#fb684b';
    		indexTextColor = '#532810';
    		arrowBgHead = 'bg_place_three_head';
    		arrowBgCenter = 'bg_place_three_center';
    		arrowBgTail = 'bg_place_three_tail';
    		roundMask = 'rn_bg_photos_three';
    	}
    	
    	if(rowData.haslltub === false){
    		lltubStyle = styles.lltubGone;
    	}
    	
    	if(rowData.hasRetail === true){
    		retialOpacity = 255;
    	}
    	
    return (
       
          <View style={{backgroundColor:'#d9d6d7', overflow:'hidden'}}>
            <View style={{flexDirection: 'row', alignItems: 'center', paddingLeft: 10, paddingRight: 10, backgroundColor:rowBg}}>
    			<View>
    				<View style={{backgroundColor:'#aaaaaa', width:6, height:80, marginLeft: 32}}/>
    				<Image source={{uri:imgSource}} style={[{alignItems: 'center', justifyContent: 'center', width:70, height:72},{position: 'absolute', top:0, left: 0}]}>
    					<Text style={{color:indexTextColor}}>
    					{index}
    					</Text>
    				</Image>
    			</View>
    			<Image source={{uri:arrowBgHead}} style={{marginLeft:32, width:40, height:70}}  resizeMode={Image.resizeMode.stretch}/>
    			<Image source={{uri:arrowBgCenter}} style={{flex:1, height:70, justifyContent:'center'}} resizeMode={Image.resizeMode.stretch}>  
    					
    				<View style={{flexDirection:'row'}}>
    				   <View style={{alignItems: 'center'}}>
    					   <Image source={{uri:'photos_small'}} style={{width:55, height:55, alignItems: 'center', justifyContent:'center'}} resizeMode={Image.resizeMode.cover}>
    						   <Image source={{uri:rowData.avatarImage}} style={{width:55, height:55}} resizeMode={Image.resizeMode.cover}>
    						   <Image source={{uri:roundMask}} style={{width:55, height:55}} resizeMode={Image.resizeMode.cover}/>
    						   </Image>
    					   </Image>
    				   
    				   </View >
    				   <View style={{ justifyContent: 'center'}}>
    						<View  style={{flexDirection:'row', alignItems: 'center'}}>
    						  <Image source={{uri:'icon_mark_retail',width:15, height:15}} resizeMode={Image.resizeMode.contain} style={{opacity:retialOpacity}}>
    						  </Image>
    						  <Text style={{marginLeft:3, fontSize: 16, color:'#555555'}}>
    							  {rowData.userName}
    						  </Text>
    						</View>
    						<Text style={lltubStyle}>
    							业务提成
    							<Text style={{color:'#f06100', fontSize:14}}>
    								{rowData.tvTub}
    							</Text>
    						</Text>
    						<Text style={{color:'#555555', fontSize:14, marginLeft:10}}>
    							{rowData.achievementType}
    							<Text style={{color:'#f06100', fontSize:14, paddingLeft:3}}>
    								{rowData.achievement}
    							</Text>
    						</Text>
    				   </View>
    				</View>
    			</Image>
    			<Image source={{uri:arrowBgTail}} style={{width:12, height:70}}  resizeMode={Image.resizeMode.stretch}/>
            </View>
          </View>
     
    );
    

    }

    render() {
      return (
        <ListView 
    	  
    	  pageSize={15}
    	  initialListSize={3}
    	  
    	  onEndReachedThreshold={1000}
    	  scrollRenderAheadDistance={2000}
    	  enableEmptySections={true}
          dataSource={this.state.dataSource}
          renderRow={this._renderRow}
        />
      );
    }
    

    }



  • 我在开发的过程中也遇到过类似的问题。
    加载Image过多的时候,真机测试表现为:
    1.android 6.0版本以下,图像加载不出来;
    2.android 6.0版本内存不断飙升直至进程崩溃。
    不知是否与你情况相似?



  • 我是用6.0sdk编译。运行在4.4上面。每行都有个头像要显示。
    你的问题解决了吗?



  • @北极熊nanook 我是用6.0sdk编译。运行在4.4上面。每行都有个头像要显示。
    你的问题解决了吗?



  • @iceskyblue 目前没有什么好的解决方法,可以关注以下github上react native issue #7408



  • @北极熊nanook 说:

    react native issue #7408

    听说WindowedListView可以。但是我没搞成功



  • @iceskyblue 好的,我尝试一下,如果成功了告诉你



  • 貌似 release 之后会快很多。

    关于 Listview 的性能,
    http://www.race604.com/react-native-scrollview-performance/ 可以参考这个。