2011-07-01 25 views
3

我的第一份午餐申请使用6.5mb,然后当我进入一个有3个标签的活动,并带有一个显示列表视图的标签时,它使用14mb!使用自定义适配器使用更多的RAM?

发生这种情况时,我从SimpleAdapter的“错误代码”到我的自定义适配器。

我想要的是在列表视图中每边两个字符串。该字符串数组中,这里是我用的人告诉我的方法是做一个不正确的方法:

String[] array= getResources().getStringArray(R.array.Names_List); 

int lengthtmp= array.length; 
for(int i=0;i<lengthtmp;i++) 
{ 
    counter++; 
    AddToList(array[i]);    
} 

adapter = new SimpleAdapter(this,list,R.layout.start_row,new String[] {"number","suraname"},new int[] {R.id.Start_Numbering,R.id.Start_Name}); 


private void AddToList(String name) { 
HashMap<String,String> temp = new HashMap<String,String>(); 


temp.put("number", Integer.toString(SortingPictures[counter-1])); 

temp.put("suraname", name); 
list.add(temp); 

    } 

有了这个代码,该活动发生RAM 10MB的。改变我的代码以使用自定义适配器之后,它采用14 MB:

使用自定义适配器时
public class ListView_Start_Adapter extends BaseAdapter{ 
private String[] SuraNames; 
private int[] PageNumber; 
private Context mContext; 
RelativeLayout relativeView; 
TextView tv_SuraName; 
TextView tv_PageNumber; 
RelativeLayout.LayoutParams param; 

public ListView_Start_Adapter(Context context, String[] SuraNames, int[] PageNumber){ 
    mContext=context; 
    this.SuraNames=SuraNames; 
    this.PageNumber=PageNumber; 
} 

@Override 
public int getCount() { 
    // TODO Auto-generated method stub 
    return SuraNames.length; 
} 

@Override 
public Object getItem(int arg0) { 
    // TODO Auto-generated method stub 
    return SuraNames[arg0]; 
} 

@Override 
public long getItemId(int arg0) { 
    // TODO Auto-generated method stub 
    return PageNumber[arg0]; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // TODO Auto-generated method stub 
    relativeView= new RelativeLayout(mContext); 
    tv_SuraName = new TextView(mContext); 
    tv_PageNumber = new TextView(mContext); 

    tv_SuraName.setText(SuraNames[position]); 
    tv_PageNumber.setText(Integer.toString(PageNumber[position])); 

    param = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT); 
    param.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 

    relativeView.addView(tv_SuraName, param); 
    relativeView.addView(tv_PageNumber); 

    return relativeView; 

} 

    } 

谁能告诉我,为什么这么多的内存使用?此自定义适配器有问题吗?

EDIT1:这是一个更好的代码是一个由dziobas建议:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    ViewHolder  holder; 

    if(convertView == null) { 
     convertView = mInflater.inflate(R.layout.start_row, parent,false); 
     holder=new ViewHolder(); 

     holder.tv_SuraName =(TextView)convertView.findViewById(R.id.Start_Name); 
     holder.tv_PageNumber = (TextView)convertView.findViewById(R.id.Start_Numbering); 
     convertView.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    holder.tv_SuraName.setText(SuraNames[position]); 
    holder.tv_PageNumber.setText(Integer.toString(PageNumber[position])); 

    return convertView; 
} 

我在这一行取得ExceptionNullPointer:“convertView = mInflater.inflate(R.layout.start_row,父母,假); “为什么?

回答

3

您不能在getView中回收视图。

它会像这样更好:

public class ListView_Start_Adapter extends BaseAdapter { 
    private String[]   SuraNames; 
    private int[]    PageNumber; 
    RelativeLayout.LayoutParams param; 
    Context      mContext; 

    public ListView_Start_Adapter(Context context, String[] SuraNames, int[] PageNumber) { 
     mContext  = context; 
     this.SuraNames = SuraNames; 
     this.PageNumber = PageNumber; 
     param   = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT); 
     param.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 
    } 

    @Override 
    public int getCount() { 
     return SuraNames.length; 
    } 

    @Override 
    public Object getItem(int arg0) { 
     return SuraNames[arg0]; 
    } 

    @Override 
    public long getItemId(int arg0) { 
     return PageNumber[arg0]; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder  holder; 
     RelativeLayout rowView; 

     if(convertView == null) { 
      //create view 
      rowView    = new RelativeLayout(mContext); 
      holder    = new ViewHolder(); 
      holder.tv_SuraName = new TextView(mContext); 
      holder.tv_PageNumber = new TextView(mContext); 
      rowView.addView(holder.tv_SuraName, param); 
      rowView.addView(holder.tv_PageNumber); 
      rowView.setTag(holder); 
     } else { 
      //recycle view 
      rowView = (RelativeLayout) convertView; 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     //fill views 
     holder.tv_SuraName.setText(SuraNames[position]); 
     holder.tv_PageNumber.setText(Integer.toString(PageNumber[position])); 

     return rowView; 
    } 

    class ViewHolder { 
     RelativeLayout relativeView; 
     TextView  tv_SuraName; 
     TextView  tv_PageNumber; 
    } 
} 

而改变视图创建。使用LayoutInflater并使用xml进行布局。

有关更多关于listview适配器效率的信息,请参阅this presentation

+0

+1我只是写了一个类似的答案。按照描述创建视图并使用convertView。另请参阅[2009年的此演示文稿](http://www.google.com/events/io/2009/sessions/TurboChargeUiAndroidFast.html)。还有一个关于如何回收视图的好视觉解释[这里](http://android.amberfog.com/?p=296)。 –

+0

请阅读Edit1,是否比创建一个编程更好地从XML膨胀? – Omar

0

您可能想要做的第一件事是开始使用传递给getView的convertView,而不是创建新视图。您将获得更高的性能(从更少的垃圾收集和更少的视图构造),并可能降低内存使用量。

2

不生成UI元素的每个条目

您的每一个条目返回一个新鲜relativeView。这将

  1. 使用更多的内存
  2. 施加更大的压力垃圾收集

使用正常的方式来实现getView

// In the class 
private LayoutInflater inflater; 

// in the constructor 
    inflater = (LayoutInflater) 
     context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

// getView() 
    if (view == null) { 
     view = inflater.inflate(R.layout.element_layout, parent, false); 
    } 

的SimpleAdapter源代码可用

请看SimpleAdapter.java。源代码是免费提供的。几乎每个适配器都有这些代码块。

快乐黑客!

相关问题