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/ 可以参考这个。


登录后回复