展会信息港展会大全

android listview性能优化实践
来源:互联网   发布日期:2015-11-26 10:10:05   浏览:2467次  

导读:在看了一些vogella的文章之后,发现关于android listview性能优化这一段很有意思,于是实践了一下,经过优化,性能确实提升不少!先看看优化前和优化后的比较:优化前的log截图:优化后的log截图:并且,在不停......

在看了一些vogella的文章之后,发现关于android listview性能优化这一段很有意思,于是实践了一下,经过优化,性能确实提升不少!

先看看优化前和优化后的比较:

优化前的log截图:

优化后的log截图:

并且,在不停滚动ListView的过程中,优化之前会出现ANR现象,在AVD上特别容易复现:

然后,优化后显得很流畅,附上对于的log截图:

下面附上相关代码分析:

ListView中的每一个Item由一个ImageView 和一个TextView组成

Layout:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="horizontal" >

<ImageView android:id="@+id/imageView"

android:layout_width="wrap_content"

android:layout_height="fill_parent" />"

<TextView android:id="@+id/textView"

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:layout_marginLeft="15dp"

android:gravity="center_vertical" />

</LinearLayout>

Activity继承自ListActivity,我故意增加了Item,方便测试,效果更明显:

public class ListViewDemo extends ListActivity{

private final String[] mItems = new String[] { "Android", "iPhone",

"WindowsMobile", "Blackberry", "WebOS", "Ubuntu", "Windows7",

"Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X",

"Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2",

"Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu",

"Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7",

"Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X",

"Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2",

"Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu",

"Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7",

"Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X",

"Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2",

"Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu",

"Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7",

"Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X",

"Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2",

"Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu",

"Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7",

"Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X",

"Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2",

"Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu",

"Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7",

"Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X",

"Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2",

"Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu",

"Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7",

"Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X",

"Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2" };

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

ListViewArrayAdapter adapter = new ListViewArrayAdapter(this, mItems);

getListView().setAdapter(adapter);

}

}

然后custom Adapter,优化之前的adapter:

@Override

public View getView(int position, View convertView, ViewGroup parent) {

long start = System.currentTimeMillis();

LayoutInflater inflater = (LayoutInflater) mContext.getLayoutInflater();

View rowView = inflater.inflate(mViewResourceId, parent, false);

TextView textView = (TextView) rowView

.findViewById(mTextViewResourceId);

ImageView imageView = (ImageView) rowView

.findViewById(mImageViewResourceId);

textView.setText(mNames[position]);

String s = mNames[position];

if (s.startsWith("Windows7") || s.startsWith("iPhone")) {

imageView.setImageResource(R.drawable.no);

} else {

imageView.setImageResource(R.drawable.yes);

}

Log.v("jerikc","cost time = " + (System.currentTimeMillis() - start));

return rowView;

}

优化之后的Adapter:

public class ListViewArrayAdapter extends ArrayAdapter<String>{

private final Activity mContext;

private final String[] mNames;

private final static int mViewResourceId = R.layout.text_image_row_layout;

private final static int mTextViewResourceId = R.id.textView;

private final static int mImageViewResourceId = R.id.imageView;

static class ViewHolder {

public TextView text;

public ImageView image;

}

public ListViewArrayAdapter(Activity context, String[] names) {

super(context, mViewResourceId, names);

this.mContext = context;

this.mNames = names;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

long start = System.currentTimeMillis();

View rowView = convertView;

if (rowView == null) {

LayoutInflater inflater = mContext.getLayoutInflater();

rowView = inflater.inflate(mViewResourceId, null);

ViewHolder viewHolder = new ViewHolder();

viewHolder.text = (TextView) rowView.findViewById(mTextViewResourceId);

viewHolder.image = (ImageView) rowView.findViewById(mImageViewResourceId);

rowView.setTag(viewHolder);

}

ViewHolder holder = (ViewHolder) rowView.getTag();

String s = mNames[position];

holder.text.setText(s);

if (s.startsWith("Windows7") || s.startsWith("iPhone")) {

holder.image.setImageResource(R.drawable.no);

} else {

holder.image.setImageResource(R.drawable.yes);

}

Log.v("jerikc","cost time = " + (System.currentTimeMillis() - start));

return rowView;

}

}

优化的大致思想就是:优化之前,每次加载item的时候,都要加载一下布局文件,然后生成一个新的row View对象,然后通过View找到对应的ImageView和TextView,正如我们所知道的那样,加载布局文件时很耗时的,特别是在操作比较频繁 情况下,这是不可忍受的,所以会导致ANR现象。

因此,我们可以重复利用已不可见的row View对象。Android中,当它决定让row View对象不可见的时候,它允许通过getView方法中的convertView参数来重复利用刚刚不可见的row View对象。

在优化的过程中,第一次加载的时候,我们需要把相关的数据保存起来,而View有一个方法setTag,该方法可用来保存一些数据结构。我们一个row View对象是由ImageView和TextView空间组成的,因此定义一个ViewHolder来保存ImageView和TextView对象。 在重复利用的过程中,只需简单修改它们的值,而不用再次findViewById。

赞助本站

人工智能实验室

相关热词: listview 性能 优化

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港