使用自定义适配器会使用更多 RAM?
我的应用程序在第一次午餐时使用了 6.5mb,然后当我输入具有 3 个选项卡的活动(其中一个选项卡显示列表视图)时,它使用了 14mb!
当我从 SimpleAdapter 的“错误代码”转向自定义适配器时,就发生了这种情况。
我想要的是列表视图中每一侧都有 2 个字符串。字符串位于数组中,这是我使用的方法,人们告诉我这是错误的方法:
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);
}
使用此代码,该活动需要 10mb 的 ram。将我的代码更改为使用自定义适配器后,它使用了 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;
}
}
谁能告诉我为什么使用自定义适配器时使用了这么多内存?这个自定义适配器有问题吗?
编辑1:这是一个比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,parent,false); “ 为什么?
my application on the first lunch uses 6.5mb, and then when I enter an activity with 3 tabs, with a tab that displays a listview, it uses 14 mb!!
This happened when I went from a "bad code" with SimpleAdapter to my Custom Adapter.
What I want is 2 strings on each side in a listview. the strings are in an array, here is the way I was using that people told me is an incorrect way to do:
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);
}
With this code, the activity takes 10mb of ram. After changing my code to use a Custom adapter, it uses 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;
}
}
Can anyone tell me why so much ram used when using a Custom adapter? Is there something wrong with this Custom adapter?
EDIT1: Is this a better code that the one suggested by 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;
}
I get ExceptionNullPointer in this line: " convertView = mInflater.inflate(R.layout.start_row, parent,false);
" Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您没有在 getView 中回收视图。
像这样会更好:
并更改视图创建。使用LayoutInflater并使用xml进行布局。
请参阅此演示文稿有关列表视图适配器效率的更多信息。
You're not recycling view in getView.
It'll much better like this:
And change view creation. Use LayoutInflater and use xml for layout.
See this presentation for more info about listview adapter efficiency.
不要为每个条目生成 UI 元素
您为每个条目返回一个新的relativeView。这会
使用正常的方式实现 getView
SimpleAdapter 源码已经有了
看看SimpleAdapter.java。源代码是免费提供的。几乎每个适配器都有这些代码块。
黑客快乐!
Don't generate a UI element for every entry
You return a fresh relativeView for every single entry. This will
Use the normal way to implement getView
The SimpleAdapter source code is available
Just look at the SimpleAdapter.java. The sourcecode is freely available. Just about every Adapter has these code block.
Happy hacking!
您可能想做的第一件事是开始使用传递给 getView 的 ConvertView 而不是创建新视图。您最终将获得更高的性能(来自更少的垃圾收集和更少的视图构造),并且可能会降低内存使用量。
The first thing that you might want to do is start using the convertView passed into getView instead of creating new views. You'll end up with higher performance (from fewer garbage collections and fewer view constructions) and probably lower memory usage.