【Android开发经验】ViewHolder到底用什么修饰?static?final?static final?
2015-01-15 15:02
489 查看
转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992
现在大家都知道用ViewHolder来实现listview的优化了,但是,ViewHolder到底要用什么来修饰呢?这种修饰有什么意义呢?在一个ListView里面,存在多少个VIewHolder实例呢?为什么VIewHolder能够减少findview的次数,优化效率呢?为了弄清楚这个问题,我做了以下测试,测试代码很简单,就是下面这些
public class MainActivity extends Activity {
public static int itemId = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView listView = new ListView(this);
listView.setAdapter(new MyAdapter());
setContentView(listView);
}
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return 50;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.item,
parent, false);
viewHolder = new ViewHolder();
viewHolder.tv = (TextView) convertView.findViewById(R.id.tv);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv.setText("item" + position);
Log.d("TAG", "position=" + position + "---" + viewHolder.toString());
return convertView;
}
}
private class ViewHolder {
// private static class ViewHolder {
// private final class ViewHolder {
// private static final class ViewHolder {
private int id;
public ViewHolder() {
id = itemId;
Log.d("TAG", "ViewHolder" + id);
itemId++;
}
TextView tv;
@Override
public String toString() {
return "--------id=" + id;
}
}
}
我简单说一下代码是什么意思,ViewHolder有一个成员变量id,在toString()使用,用来区分不同的ViewHolder,在构造函数中,对id进行赋值,itemId是一个静态变量,每初始化一次就+1,我们可以根据构造函数的打印次数,来计算ViewHolder的实例化次数,根据toString()可以来判断到底是使用了哪一个ViewHolder。getVIew中的写法是固定的,下面是测试结果:
private class ViewHolder修饰,界面内可见的item数量是9个,ViewHolder初始化了10次,之后开始复用ViewHolder。
private static class ViewHolder修饰,界面内可见的item数量是9个,ViewHolder初始化了10次,之后开始复用ViewHolder。
private final class ViewHolder修饰,界面内可见的item数量是9个,ViewHolder初始化了10次,之后开始复用ViewHolder。
private static final class ViewHolder修饰,完全一样!
其实一上来我就贴一张图就ok了,因为这几种完全一样,不管用什么修饰,ViewHolder都会初始化当前界面可见item的数量+1次,和convertView的实例化次数是一样的,因此,我么不管使用什么修饰都是没问题的,也是没必要的。
static修饰类,在这里是静态内部类,并不是说只存在一个实例,而是可以访问外部类的静态变量,final修饰类则是不让该类继承,我们这里使用final毫无根据,所以,以后写ViewHolder的时候,可以不纠结了,加什么加啊,什么都不用加!
----------------------------------------------------------------------------------------
今天又请教了公司一个大神,他的回答如下:
这篇文章中没有提到加载时机的问题吧。在我的理解中:静态内部类主要作用就是,内部类是否需要隔离“外部类的this对象(指针)”。内部类是有 this 指针的,可以“直接”访问外部类的 成员变量和成员函数(包括私有的成员)。而静态内部类,没有这个this指针,所以无法“直接”调用。
个人的习惯,我通常会把内部静态类,作为一个单独的java文件。
但是Android代码中,却经常使用的Builder,LayoutParams都是以静态内部类的方式存在啊。我们可以根据实际使用情况来效仿。
另外还要提一点,内部静态类(特别是私有内部静态类),在代码混淆上效果更好。会增加反编译的难度。
-------------------------------------------------------
对于这篇文章,我理解。ViewHolder的构造和复用,与静不静态没关。核心是ListView(AdapterView),通过getView(int position, View convertView, ViewGroup parent) 的convertView会为开发者传入一个可以复用的对象。开发者需要利用该对象,减少应用内存的消耗。
如果从减少内存消耗的角度来开。我认为ViewHolder还是应该修饰成static比较好。这样ViewHolder中可以减少MainActivity的this指针,由于减少了一个this指针的引用,也会对MainActivity的引用计数大大减少。MainActivity的this指针继承于android的Context上下文,对于Context的回收遗漏,是Android内存管理中很大的问题。我们减少了对Context的引用,可以更容易减少Context引用计数出现问题。
现在大家都知道用ViewHolder来实现listview的优化了,但是,ViewHolder到底要用什么来修饰呢?这种修饰有什么意义呢?在一个ListView里面,存在多少个VIewHolder实例呢?为什么VIewHolder能够减少findview的次数,优化效率呢?为了弄清楚这个问题,我做了以下测试,测试代码很简单,就是下面这些
public class MainActivity extends Activity {
public static int itemId = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView listView = new ListView(this);
listView.setAdapter(new MyAdapter());
setContentView(listView);
}
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return 50;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.item,
parent, false);
viewHolder = new ViewHolder();
viewHolder.tv = (TextView) convertView.findViewById(R.id.tv);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv.setText("item" + position);
Log.d("TAG", "position=" + position + "---" + viewHolder.toString());
return convertView;
}
}
private class ViewHolder {
// private static class ViewHolder {
// private final class ViewHolder {
// private static final class ViewHolder {
private int id;
public ViewHolder() {
id = itemId;
Log.d("TAG", "ViewHolder" + id);
itemId++;
}
TextView tv;
@Override
public String toString() {
return "--------id=" + id;
}
}
}
我简单说一下代码是什么意思,ViewHolder有一个成员变量id,在toString()使用,用来区分不同的ViewHolder,在构造函数中,对id进行赋值,itemId是一个静态变量,每初始化一次就+1,我们可以根据构造函数的打印次数,来计算ViewHolder的实例化次数,根据toString()可以来判断到底是使用了哪一个ViewHolder。getVIew中的写法是固定的,下面是测试结果:
private class ViewHolder修饰,界面内可见的item数量是9个,ViewHolder初始化了10次,之后开始复用ViewHolder。
private static class ViewHolder修饰,界面内可见的item数量是9个,ViewHolder初始化了10次,之后开始复用ViewHolder。
private final class ViewHolder修饰,界面内可见的item数量是9个,ViewHolder初始化了10次,之后开始复用ViewHolder。
private static final class ViewHolder修饰,完全一样!
其实一上来我就贴一张图就ok了,因为这几种完全一样,不管用什么修饰,ViewHolder都会初始化当前界面可见item的数量+1次,和convertView的实例化次数是一样的,因此,我么不管使用什么修饰都是没问题的,也是没必要的。
static修饰类,在这里是静态内部类,并不是说只存在一个实例,而是可以访问外部类的静态变量,final修饰类则是不让该类继承,我们这里使用final毫无根据,所以,以后写ViewHolder的时候,可以不纠结了,加什么加啊,什么都不用加!
----------------------------------------------------------------------------------------
今天又请教了公司一个大神,他的回答如下:
这篇文章中没有提到加载时机的问题吧。在我的理解中:静态内部类主要作用就是,内部类是否需要隔离“外部类的this对象(指针)”。内部类是有 this 指针的,可以“直接”访问外部类的 成员变量和成员函数(包括私有的成员)。而静态内部类,没有这个this指针,所以无法“直接”调用。
个人的习惯,我通常会把内部静态类,作为一个单独的java文件。
但是Android代码中,却经常使用的Builder,LayoutParams都是以静态内部类的方式存在啊。我们可以根据实际使用情况来效仿。
另外还要提一点,内部静态类(特别是私有内部静态类),在代码混淆上效果更好。会增加反编译的难度。
-------------------------------------------------------
对于这篇文章,我理解。ViewHolder的构造和复用,与静不静态没关。核心是ListView(AdapterView),通过getView(int position, View convertView, ViewGroup parent) 的convertView会为开发者传入一个可以复用的对象。开发者需要利用该对象,减少应用内存的消耗。
如果从减少内存消耗的角度来开。我认为ViewHolder还是应该修饰成static比较好。这样ViewHolder中可以减少MainActivity的this指针,由于减少了一个this指针的引用,也会对MainActivity的引用计数大大减少。MainActivity的this指针继承于android的Context上下文,对于Context的回收遗漏,是Android内存管理中很大的问题。我们减少了对Context的引用,可以更容易减少Context引用计数出现问题。
相关文章推荐
- 【Android开发经验】ViewHolder到底用什么修饰?static?final?static final?
- 【Android开发经验】ViewHolder到底用什么修饰?static?final?static final?
- android - ViewHolder到底用什么修饰?static?final?static final?
- ViewHolder到底用什么修饰?static?final?static final?
- ViewHolder到底用什么修饰?static?final?static final?
- viewholder到底用什么修饰/
- 【Android游戏开发之三】剖析 SurfaceView ! Callback以及SurfaceHolder!!
- 【Android开发经验】来来来,同学,咱们讨论一下“只能在UI主线程更新View”这件小事
- Static和final修饰变量、方法、类的时候含义分别是什么?
- Android中ViewHolder模式开发的详细解释
- 【Android游戏开发之三】详细剖析 SurfaceView ! Callback以及SurfaceHolder!!
- Android中利用ViewHolder优化自定义Adapter的典型写法(讨论ViewHolder的修饰方式)
- java中final关键字到底修饰了什么
- Android游戏开发入门:SurfaceView+SurfaceHolder+Thread
- 【Android游戏开发之三】剖析 SurfaceView ! Callback以及SurfaceHolder!!
- J2SE基础夯实系列之String字符串不可变的理解,不可变类,final关键字到底修饰了什么
- J2SE基础夯实系列之String字符串不可变的理解,不可变类,final关键字到底修饰了什么
- Android开发之播放器中涉及的Surface,SurfaceView,SurfaceHolder基础
- 【Android游戏开发之三】详细剖析 SurfaceView ! Callback以及SurfaceHolder!!
- final关键字到底修饰了什么?