提升Android ListView性能的几个技巧
2014-09-17 19:50
274 查看
ListView如何运作的?
ListView是设计应用于对可扩展性和高性能要求的地方。实际上,这就意味着ListView有以下2个要求:
尽可能少的创建View;
只是绘制和布局在屏幕上可见的子View。
理解第一点很简单:通过布局xml文件在创建View并显示是很昂贵耗时耗资源的操作。尽管布局文件已经编译打包成了二进制形式以便于更高效的语法解析,但是创建View仍然需要通过一个特殊的XML树,并实例化所有需要响应的View。
ListView通过回收一些不可见的Views,通常在Android源码中称为“ScrapView(废弃的View)”来解决这个问题。这及意味着开发者只需要简单的更新每行的内容而不需要针对每个单独的行的布局来创建View。
为了实现第二点,在我们滑动屏幕时,ListView通过使用View回收器来增加低于或者高于当当前窗口的Views,并当前活动的Views移动到一个可回收池中。这样的话,ListView只需要在内存中保持足够多的Views去填充分配空间中的布局和一些额外的可回收Views,即使当你的Adapter有上百个items的适合。它会使用不同的方法去填充行之间的空间,从顶部或者底部等等,具体取决于窗口是如何变化的。
下面这个图很直观的展示了当你按下ListView的时候发生了什么:
View Code
人机交互知识
做到在每一行异步加载很多资源,是一个高性能的ListView的必经之路。但是,在滑动屏幕时,如果你一味的在每一个getView()调用里面都去启动一个异步的操作,造成的结果就是你会浪费大量资源。因为行被频繁回收,造成大部分返回的结果会被丢弃。
考虑到实际的人机交互情况,在ListView适配器中,在每一行中都不应该去触发任何异步操作。也就是说,在ListView中有fling(快速滑动)操作时,启动任何异步操作都没有任何意义。一旦滚动停止或即将停止,才是开始真正显示每行的内容的时候。
我不会发布一个代码示例贴在这里,因为其中涉及到的代码太多。Romain Guy写了一个很经典的应用:Shelves app,其中有一个很好的的示例。当GridView停止滑动时不做其他事情时,它就开始触发从而去异步加载书的封面资源。即使在滑动时,你也可以展示缓存中的内容,通过使用memory cache来平衡交互。这真是个好主意!
以上
我强烈推荐你看下Romain Guy和Adam Powell的关于ListView的讨论,里面涵盖了很多这篇文章的东西。你可以看看Pattrn,可以看到这里面的几个技巧是如何在应用中运用的。
希望它是你在Android开发中一个很有用的参考:–)
Long Luo at PM17:30 Feb. 14th, 2014 @Shenzhen, China.
original link:http://longluo.github.io/blog/20140214/some_tips_about_android_listview_performence/
written by Frank Luo posted at http://longluo.github.io
ListView是设计应用于对可扩展性和高性能要求的地方。实际上,这就意味着ListView有以下2个要求:
尽可能少的创建View;
只是绘制和布局在屏幕上可见的子View。
理解第一点很简单:通过布局xml文件在创建View并显示是很昂贵耗时耗资源的操作。尽管布局文件已经编译打包成了二进制形式以便于更高效的语法解析,但是创建View仍然需要通过一个特殊的XML树,并实例化所有需要响应的View。
ListView通过回收一些不可见的Views,通常在Android源码中称为“ScrapView(废弃的View)”来解决这个问题。这及意味着开发者只需要简单的更新每行的内容而不需要针对每个单独的行的布局来创建View。
为了实现第二点,在我们滑动屏幕时,ListView通过使用View回收器来增加低于或者高于当当前窗口的Views,并当前活动的Views移动到一个可回收池中。这样的话,ListView只需要在内存中保持足够多的Views去填充分配空间中的布局和一些额外的可回收Views,即使当你的Adapter有上百个items的适合。它会使用不同的方法去填充行之间的空间,从顶部或者底部等等,具体取决于窗口是如何变化的。
下面这个图很直观的展示了当你按下ListView的时候发生了什么:
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; ... holder.position = position; new ThumbnailTask(position, holder) .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null); return convertView; } private static class ThumbnailTask extends AsyncTask { private int mPosition; private ViewHolder mHolder; public ThumbnailTask(int position, ViewHolder holder) { mPosition = position; mHolder = holder; } @Override protected Cursor doInBackground(Void... arg0) { // Download bitmap here } @Override protected void onPostExecute(Bitmap bitmap) { if (mHolder.position == mPosition) { mHolder.thumbnail.setImageBitmap(bitmap); } } } private static class ViewHolder { public ImageView thumbnail; public int position; }
View Code
人机交互知识
做到在每一行异步加载很多资源,是一个高性能的ListView的必经之路。但是,在滑动屏幕时,如果你一味的在每一个getView()调用里面都去启动一个异步的操作,造成的结果就是你会浪费大量资源。因为行被频繁回收,造成大部分返回的结果会被丢弃。
考虑到实际的人机交互情况,在ListView适配器中,在每一行中都不应该去触发任何异步操作。也就是说,在ListView中有fling(快速滑动)操作时,启动任何异步操作都没有任何意义。一旦滚动停止或即将停止,才是开始真正显示每行的内容的时候。
我不会发布一个代码示例贴在这里,因为其中涉及到的代码太多。Romain Guy写了一个很经典的应用:Shelves app,其中有一个很好的的示例。当GridView停止滑动时不做其他事情时,它就开始触发从而去异步加载书的封面资源。即使在滑动时,你也可以展示缓存中的内容,通过使用memory cache来平衡交互。这真是个好主意!
以上
我强烈推荐你看下Romain Guy和Adam Powell的关于ListView的讨论,里面涵盖了很多这篇文章的东西。你可以看看Pattrn,可以看到这里面的几个技巧是如何在应用中运用的。
希望它是你在Android开发中一个很有用的参考:–)
Long Luo at PM17:30 Feb. 14th, 2014 @Shenzhen, China.
original link:http://longluo.github.io/blog/20140214/some_tips_about_android_listview_performence/
written by Frank Luo posted at http://longluo.github.io
相关文章推荐
- 提升磁盘IO性能的几个技巧
- 提升磁盘IO性能的几个技巧
- 提升磁盘IO性能的几个技巧
- 提升Android ListView性能的几个技巧
- 提升磁盘IO性能的几个技巧
- 提升Android ListView性能的几个技巧
- 提升磁盘IO性能的几个技巧
- 提升磁盘IO性能的几个技巧
- 提升Android ListView性能的几个技巧
- 提升Android ListView性能的几个技巧
- 提升Android ListView性能的几个技巧
- 提升磁盘IO的性能的几个技巧
- 提升Android ListView性能的几个技巧
- 提升Android ListView性能的几个技巧
- 提升磁盘IO性能的几个技巧
- 提升磁盘IO性能的几个技巧
- 提升磁盘IO性能的几个技巧(转)
- FastDFS :提升磁盘IO性能的几个技巧
- 提升App销量的几个技巧
- PostgreSQL 数据库性能提升的几个方面