正文
一、新浪微博
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.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 |
三、总结
从测试结果来看与ViewHolder性能非常接近,不会出现tag图片变小的问题(关于图片变小的问题,有朋友说是TAG中的元素对大小和位置有记忆),也能有效的减少findViewById的执行次数,这里建议完全可以取代ViewHolder。
关于ListView内部Adapter的心得大家可以看一下上文的总结4.1。
四、考虑
关于静态内部类这里不是很理解,是否能应用方案五还有待验证。
五、后期维护
2011-4-29 来自Stony Wang关于Tag的解释:
Stony Wang
tag的用途应该是仿照delphi的来的,设置一个关联的数据。
简单的说就是,你的UI控件有时候显示的内容带源于(绑定?)某个数据或者对象实例。
当你处理一些事件的时候,不推荐从UI上来重新获取,而是从Tag里面取出来。
举一个例子是,有一个按钮,一开始显示"0",然后每按一次计数增1。
每次click的时候,
1 从btn.getText()再转回Integer
2 从tag里面把之前设好的Integer拿出来,加一,再settag?
如果觉得1和2区别不大的话,那么如果显示的内容不是"0",而是"已经点了0次"呢?
更新UI的时候,可以将关联的对象放到tag里面,在处理相关触发事件的时候,可以方便的获取原始的数据。
ListView的Tag用法也不算很错,而是用的时候没有注意设置的时候要注意“对称”。
Tag本身可以理解成放ViewHolder,那么和ViewHolder的加速只不过是存放的位置不同,加速效果基本一致。
“对称”我所指的内容是:
不管你要显示的数据的逻辑是如何的,如果你设置了某个View的宽度,那么在任何一种数据的填充UI逻辑里面,不可以有不设置这个View宽度的代码路径。
简单的例子就是,我根据某个布尔值,如果是false的话,将ImageView设置为View.INVISIBLE
if ( item.isHidden()){
mImage.setVisibility(View.INVISIBLE);
}
这样是错误的,因为如果这里缓存的UI控件的状态会被复用到其它item上,而这个item恰巧可能是需要显示的。
必须补上else语句
else{
mImage.setVisibility(View.VISIBLE);
}
这个估计就是那位仁兄拖动图片变小的原因了。
最后说一下,ListView控件条目部分,一共产生的条目是屏幕能容纳的数目+2(还是+1?我记不清楚了),然后循环使用。
结束
优化ListView不仅仅只有对convertView的优化,还有许多这样那样的技巧,欢迎大家交流与分享 :)
本文转自over140 51CTO博客,原文链接:http://blog.51cto.com/over140/582135,如需转载请自行联系原作者