前言缓存
在上一篇ListView性能优化之视图缓存咱们讨论了Google I/O中的优化方法,在各个论坛发帖后获得了不错的反馈,诸如:使用ViewHolder技术Tag的问题,利用HashMap自行存储的方案等。这里结合新浪微博中主界面的作法及测试数据与你们进一步探讨。
性能优化
文章优化
[Android]ListView性能优化之视图缓存 [本文的上篇]
ui
[Android]ListView性能优化之视图缓存 [JavaEye讨论帖]
this
正文spa
1、新浪微博code
1.1 截图
1.2 反编译后相关代码
HomeListActivity
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、测试方案(方案五)
按照新浪微博相似的作法进行测试。
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;
}
TestItemLayout
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);
}
}
2.2 测试结果
次数 |
4个子元素 |
10个子元素 |
第一次 |
347 |
460 |
第二次 |
310 |
477 |
第三次 |
324 |
508 |
第四次 |
339 |
492 |
第五次 |
341 |
465 |
3、总结
从测试结果来看与ViewHolder性能很是接近,不会出现tag图片变小的问题(关于图片变小的问题,有朋友说是TAG中的元素对大小和位置有记忆),也能有效的减小findViewById的执行次数,这里建议彻底能够取代ViewHolder。
关于ListView内部Adapter的心得你们能够看一下上文的总结4.1。
4、考虑
关于静态内部类这里不是很理解,是否能应用方案五还有待验证。
5、后期维护
2011-4-29 来自Stony Wang关于Tag的解释:
结束
优化ListView不单单只有对convertView的优化,还有许多这样那样的技巧,欢迎你们交流与分享 :)