[转载]Android ListView性能优化之视图缓存(续)

[转载][Android]ListView性能优化之视图缓存(续) – 农民伯伯 – 博客园.

前言

在上一篇ListView性能优化之视图缓存我们讨论了Google I/O中的优化方法,在各个论坛发帖后得到了不错的反馈,诸如:使用ViewHolder技术Tag的问题,利用HashMap自行存储的方案等。这里结合新浪微博中主界面的做法及测试数据与大家进一步探讨。

声明

欢迎转载,但请保留文章原始出处:)

博客园:http://www.cnblogs.com

农民伯伯: http://over140.cnblogs.com

文章

[Android]ListView性能优化之视图缓存 [本文的上篇]

[Android]ListView性能优化之视图缓存 [JavaEye讨论帖]

正文

一、新浪微博

1.1  截图

(来自网络)

1.2  反编译后相关代码

public View getView(int paramInt, View paramView, ViewGroup paramViewGroup)
{
int i = --paramInt;
int j = -1;
if (i == j);
for (Object localObject1 = HomeListActivity.this.getReloadView(); ; localObject1 = HomeListActivity.this.getLoadMoreView())
{
label26: return localObject1;
int k = HomeListActivity.this.mList.size();
int l = paramInt;
int i1 = k;
if (l != i1)
break;
}
boolean bool1 = true;
boolean bool2 = null;
String str1;
label110: Object localObject2;
if (StaticInfo.mUser == null)
{
List localList1 = HomeListActivity.this.mList;
int i2 = paramInt;
str1 = ((MBlog)localList1.get(i2)).uid;
List localList2 = HomeListActivity.this.mList;
int i3 = paramInt;
String str2 = ((MBlog)localList2.get(i3)).uid;
String str3 = str1;
if (!str2.equals(str3))
break label271;
int i4 = 1;
label156: if (paramView != null)
break label277;
HomeListActivity localHomeListActivity1 = HomeListActivity.this;
ListView localListView1 = HomeListActivity.this.mLvHome;
List localList3 = HomeListActivity.this.mList;
int i5 = paramInt;
MBlog localMBlog1 = (MBlog)localList3.get(i5);
HomeListActivity localHomeListActivity2 = HomeListActivity.this;
int i6 = paramInt;
boolean bool4 = localHomeListActivity2.isNewCommer(i6);
int i7 = HomeListActivity.this.mReadMode;
localObject2 = new MBlogListItemView(localHomeListActivity1, localListView1, localMBlog1, bool1, bool2, i4, bool4, i7);
}
while (true)
{
localObject1 = localObject2;
break label26:
str1 = StaticInfo.mUser.uid;
break label110:
label271: boolean bool3 = null;
break label156:
label277: localObject2 = paramView;
try
{
MainListItemView localMainListItemView = (MainListItemView)localObject2;
List localList4 = HomeListActivity.this.mList;
int i8 = paramInt;
Object localObject3 = localList4.get(i8);
HomeListActivity localHomeListActivity3 = HomeListActivity.this;
int i9 = paramInt;
boolean bool5 = localHomeListActivity3.isNewCommer(i9);
int i10 = HomeListActivity.this.mReadMode;
boolean bool6 = bool1;
boolean bool7 = bool2;
localMainListItemView.update(localObject3, bool6, bool7, bool5, i10);
}
catch (Exception localException)
{
HomeListActivity localHomeListActivity4 = HomeListActivity.this;
ListView localListView2 = HomeListActivity.this.mLvHome;
List localList5 = HomeListActivity.this.mList;
int i11 = paramInt;
MBlog localMBlog2 = (MBlog)localList5.get(i11);
HomeListActivity localHomeListActivity5 = HomeListActivity.this;
int i12 = paramInt;
boolean bool8 = localHomeListActivity5.isNewCommer(i12);
int i13 = HomeListActivity.this.mReadMode;
localObject2 = new MBlogListItemView(localHomeListActivity4, localListView2, localMBlog2, bool1, bool2, bool3, bool8, i13);
}
}
}

代码说明:

代码流程已经比较混乱,但是这里能看到并没有直接的inflate,而是自定义了继承自LinearLayout的MBlogListItemView。

MBlogListItemView
public MBlogListItemView(Context paramContext, ListView paramListView, MBlog paramMBlog, boolean paramBoolean1, boolean paramBoolean2, boolean paramBoolean3, boolean paramBoolean4, int paramInt)
{
super(paramContext);
this.context = paramContext;
this.parent = paramListView;
this.mBlog = paramMBlog;
String str1 = paramContext.getCacheDir().getAbsolutePath();
this.mCacheDir = str1;
String str2 = paramContext.getFilesDir().getAbsolutePath();
this.mFileDir = str2;
((LayoutInflater)paramContext.getSystemService("layout_inflater")).inflate(2130903061, this);
TextView localTextView1 = (TextView)findViewById(2131624016);
this.mName = localTextView1;
TextView localTextView2 = (TextView)findViewById(2131624041);
this.mDate = localTextView2;
TextView localTextView3 = (TextView)findViewById(2131624018);
this.mContent = localTextView3;
TextView localTextView4 = (TextView)findViewById(2131624046);
this.mSubContent = localTextView4;
ImageView localImageView1 = (ImageView)findViewById(2131624040);
this.mIconV = localImageView1;
ImageView localImageView2 = (ImageView)findViewById(2131624042);
this.mIconPic = localImageView2;
ImageView localImageView3 = (ImageView)findViewById(2131624044);
this.mUploadPic1 = localImageView3;
ImageView localImageView4 = (ImageView)findViewById(2131623979);
this.mUploadPic2 = localImageView4;
TextView localTextView5 = (TextView)findViewById(2131624047);
this.tvForm = localTextView5;
TextView localTextView6 = (TextView)findViewById(2131623989);
this.tvComment = localTextView6;
this.tvComment.setOnClickListener(this);
TextView localTextView7 = (TextView)findViewById(2131623988);
this.tvRedirect = localTextView7;
this.tvRedirect.setOnClickListener(this);
ImageView localImageView5 = (ImageView)findViewById(2131624049);
this.imComment = localImageView5;
this.imComment.setOnClickListener(this);
ImageView localImageView6 = (ImageView)findViewById(2131624048);
this.imRedirect = localImageView6;
this.imRedirect.setOnClickListener(this);
ImageView localImageView7 = (ImageView)findViewById(2131624043);
this.imGpsIcon = localImageView7;
ImageView localImageView8 = (ImageView)findViewById(2131624013);
this.mPortrait = localImageView8;
LinearLayout localLinearLayout = (LinearLayout)findViewById(2131624045);
this.mSubLayout = localLinearLayout;
this.mReadMode = paramInt;
MBlogListItemView localMBlogListItemView = this;
MBlog localMBlog = paramMBlog;
boolean bool1 = paramBoolean1;
boolean bool2 = paramBoolean2;
boolean bool3 = paramBoolean4;
int i = paramInt;
localMBlogListItemView.update(localMBlog, bool1, bool2, bool3, i);
this.mUploadPic1.setOnClickListener(this);
this.mUploadPic2.setOnClickListener(this);
}

    代码说明:

      a).  MBlogListItemView extends LinearLayout implements MainListItemView
      b).  inflate(2130903061,this)这个数字代表R.layout.itemview。
 二、测试方案(方案五)

    按照新浪微博类似的做法进行测试。

    2.1  测试代码

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 开始计时
long startTime = System.nanoTime();

TestItemLayout item;
if (convertView == null) {
item = new TestItemLayout(BaseAdapterActivity.this);
} else
item = (TestItemLayout) convertView;
item.icon1.setImageResource(R.drawable.icon);
item.text1.setText(mData[position]);
item.icon2.setImageResource(R.drawable.icon);
item.text2.setText(mData[position]);

// 停止计时
long endTime = System.nanoTime();
// 计算耗时
long val = (endTime – startTime) / 1000L;
Log.e(“Test”, “Position:” + position + “:” + val);
if (count < 100) { if (val < 2000L) { sum += val; count++; } } else mTV.setText(String.valueOf(sum / 100L) + ":" + nullcount);// 显示统计结果 return item; } [/java]   TestItemLayout [java] public class TestItemLayout extends LinearLayout { public TextView text1; public ImageView icon1; public TextView text2; public ImageView icon2; public TestItemLayout(Context context) { super(context); ((LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate( R.layout.list_item_icon_text, this); icon1 = (ImageView) findViewById(R.id.icon1); text1 = (TextView) findViewById(R.id.text1); icon2 = (ImageView) findViewById(R.id.icon2); text2 = (TextView) findViewById(R.id.text2); } } [/java] 2.2  测试结果

次数 4个子元素 10个子元素
第一次 347 460
第二次 310 477
第三次 324 508
第四次 339 492
第五次 341 465

三、总结

从测试结果来看与ViewHolder性能非常接近,不会出现tag图片变小的问题(关于图片变小的问题,有朋友说是TAG中的元素对大小和位置有记忆),也能有效的减少findViewById的执行次数,这里建议完全可以取代ViewHolder。

关于ListView内部Adapter的心得大家可以看一下上文的总结4.1。

四、考虑

关于静态内部类这里不是很理解,是否能应用方案五还有待验证。

结束

优化ListView不仅仅只有对convertView的优化,还有许多这样那样的技巧,欢迎大家交流与分享 🙂

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏