本文内容:adapter,listview的优化,RecycleBi,google大会推荐优化,

实现ListView的过程,Adapter起到了至关重要的作用,不仅仅因为getview()方法。那么,先从Adapter说起~

Adapter:

    它在ListView和数据源之间起到桥梁的作用,避免listview和数据源直接接触,而导致因为数据源的复杂性使listview显得臃肿。

  Adapter,适配器,把复杂的数据源适配给listview,很容易联想到适配器模式。

 

下面是几种常用的Adapter:

  •  ArrayAdapter:简单易用的Adapter,通常用于数组或list集合的数据源(多个值包装成多个列表项)。
  •  simpleAdapter:并不见得、功能强大的Adapter,可用于list集合的多个对象包装成多个列表项。
  •  simpleCursorAdapter:与上相似,但是用于包装jCursor(数据库游标)提供的数据源。
  • BaseAdapter:通常用于被扩展。扩展BaseAdapter可以对各列表项进行最大限度的定制。

下面是listview的优化:

增加优化一:convertView的使用,主要优化加载布局问题

  1.listivew每次滚动都会调用gitview()方法,所以优化gitview是重中之重。

    下面是getview()在Adapter类的源码,这个没有实现,要看重点部分已经颜色标记。无非是View convertView的介绍~

/**
     * Get a View that displays the data at the specified position in the data set. You can either
     * create a View manually or inflate it from an XML layout file. When the View is inflated, the
     * parent View (GridView, ListView...) will apply default layout parameters unless you use
     * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
     * to specify a root view and to prevent attachment to the root.
     *
     * @param position The position of the item within the adapter's data set of the item whose view
     *        we want.
     * @param convertView The old view to reuse, if possible. Note: You should check that this view
     *        is non-null and of an appropriate type before using. If it is not possible to convert
     *        this view to display the correct data, this method can create a new view.
     *        Heterogeneous lists can specify their number of view types, so that this View is
     *        always of the right type (see {@link #getViewTypeCount()} and
     *        {@link #getItemViewType(int)}).
     * @param parent The parent that this view will eventually be attached to
     * @return A View corresponding to the data at the specified position.
     */
    View getView(int position, View convertView, ViewGroup parent);

大家对于 convertView = null优化方法的使用已经了然于胸,但是我那个纠结,就知道是缓存了listview里面已经加载好的view(下文会讲解)。

核心代码如下:

     这部分代码很简单,如果没有缓存就加载布局,如果有缓存就直接用convertView对象。所以这样就不用滑动listview的时候

调用getView()方法每次都去加载布局了(如果改布局已经加载)。

View view;
if(convertView == null){
view = LayoutInfalter.from(getContext()).inflate(resourceID,null)
}
else{
view = convertView
}

表示宝宝一开始对 LayoutInfalter.from(getContext()).inflate(resourceID,null) 一脸蒙蔽,然后找到了解释。

//加载布局管理器
LayoutInflater inflater = LayoutInflater.from(context);
//将xml布局转换为view对象
convertView = inflater.inflate(R.layout.item_myseallist,parent, false);
//利用view对象,找到布局中的组件
convertView.findViewById(R.id.delete);// 删除

增加优化二:内部类ViewHolder的使用。

代码如下主要优化getView方法中每次回调用findviewByID()方法来获取一次控件的代码。

新增加内部类ViewHolder,用于对控件的实力存储进行缓存。

  • convertView为空时,viewHolder会将空间的实力存放在ViewHolder里,然后用setTag方法讲viewHolder对象存储在view里。
  • convertView不为空时,用getTag方法获取viewHolder对象.
//getView核心代码
ViewHolder viewHolder;
if(convertView == null){
viewHolder = new ViewHolder();
viewHolder.fruitImage = (ImageView) view.findViewByID(R.id.fruit_image);
view.setTage(viewHolder);//讲ViewHolder存储在View中

}else{
view = convertView;
viewHolder = ViewHolder view.getTag();//重获取viewHolder
}
viewHolder.fruitImage.setImageResource(fruit.getIMageID);

//内部类
class ViewHolder{
ImageView fruitImage;
}

可以看到方案一二目的很明确:第一个是优化加载布局,第二个是优化加载控件。

回到我问题~convertView存储的问题。

有没有想过ListView加载成千上万的数据为什么不出OOM错误?

最主要的是因为RecycleBin机制。

  • listview的许多view呈现在Ui上,这样的View对我们来说是可见的,可以称为OnScreen的view(也为ActionView)。
  • view被上滚移除屏幕,这样的view称为offScreenView(也称为ScrapView)。
  • 然后ScrapView会被listview删除,而RecycleView会将这部分保存。
  • 而listview底部需要显示的view会从RecycleBin里面取出一个ScrapView。

将其作为convertView参数传递过去,

  • 从而达到View复用的目的,这样就不必在Adapter的getView方法中执行LayoutInflater.inflate()方法了(不用加载布局了有木有)。

在RecycleBin里面有两个数组,看名字就知道了Actionview和ScrapViews.

/**
         * Views that were on screen at the start of layout. This array is populated at the start of
         * layout, and at the end of layout all view in mActiveViews are moved to mScrapViews.
         * Views in mActiveViews represent a contiguous range of Views, with position of the first
         * view store in mFirstActivePosition.
         */
        private View[] mActiveViews = new View[0];

        /**
         * Unsorted views that can be used by the adapter as a convert view.
         */
        private ArrayList<View>[] mScrapViews;

 原理如下:

Google推荐优化方案: 

public View getView(int position, View convertView, ViewGroup parent) {
   3:     Log.d("MyAdapter", "Position:" + position + "---"
   4:             + String.valueOf(System.currentTimeMillis()));
   5:     ViewHolder holder;
   6:     if (convertView == null) {
   7:         final LayoutInflater inflater = (LayoutInflater) mContext
   8:                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   9:         convertView = inflater.inflate(R.layout.list_item_icon_text, null);
  10:         holder = new ViewHolder();
  11:         holder.icon = (ImageView) convertView.findViewById(R.id.icon);
  12:         holder.text = (TextView) convertView.findViewById(R.id.text);
  13:         convertView.setTag(holder);
  14:     } else {
  15:         holder = (ViewHolder) convertView.getTag();
  16:     }
  17:     holder.icon.setImageResource(R.drawable.icon);
  18:     holder.text.setText(mData[position]);
  19:     return convertView;
  20: }
  21:
  22: static class ViewHolder {
  23:     ImageView icon;
  24:
  25:     TextView text;

    推荐几个链接:listview源码理解:很长,我是没看完~http://www.bkjia.com/Androidjc/1037874.html。取其中一张图,源码不是最新版本。

           RecycleBin机制:http://www.2cto.com/kf/201604/497754.html。解决了我的疑问。

列举下真正意义上的优化:http://www.xuanyusong.com/archives/1252。

致敬前辈。如果有错误请提出。

本文出处:http://www.cnblogs.com/yuhanghzsd/p/5595532.html       

      2016-06-18       

           

Android优化系列之ListView优化老生常谈的更多相关文章

  1. [MySQL性能优化系列]LIMIT语句优化

    1. 背景 假设有如下SQL语句: SELECT * FROM table1 LIMIT offset, rows 这是一条典型的LIMIT语句,常见的使用场景是,某些查询返回的内容特别多,而客户端处 ...

  2. Mysql优化系列之数据类型优化

    本篇是优化系列的第一篇:数据类型 为了不产生赘述,尽量用简洁的语言来描述. 在选择数据类型之前,首先要知道几个原则: 更小的通常更好 尽量使用可以正确存储数据的最小数据类型.更小的数据类型意味着更快, ...

  3. Android开发系列之ListView

    上篇博客解决了Android客户端通过WebService与服务器端程序进行交互的问题,这篇博客重点关注两个问题,一个是Android应用程序如何与本机文件型数据库SQLite进行交互,另一问题则是如 ...

  4. Android性能优化系列之电量优化

    电量消耗的计算与统计是一件麻烦而且矛盾的事情,记录电量消耗本身也是一个费电量的事情,随着Android开的性能要求越来越高,电量的优化,也显得格外重要,一个耗电的应用,用户肯定会毫不犹豫的进行卸载,所 ...

  5. Android开发系列之性能优化

    一直想整理一篇关于Android性能优化的博客,正好今天借鉴一些书籍资料,总结一下自己对于这块的一些认识.相信大家都听说过16ms的原则,即每两个画面之间的绘制时间间隔不能超过16ms,否则人眼能够感 ...

  6. 数据库优化系列——SQL性能优化十条建议

    1.查询的模糊匹配  尽量避免在一个复杂查询里面使用 LIKE '%parm1%'—— 红色标识位置的百分号会导致相关列的索引无法使用,最好不要用. 解决办法: 其实只需要对该脚本略做改进,查询速度便 ...

  7. PLSQL_性能优化系列04_Oracle Optimizer优化器

    2014-09-25 Created By BaoXinjian

  8. ElasticSearch优化系列七:优化建议

    尽量运行在Sun/Oracle JDK1.7以上环境中,低版本的jdk容易出现莫名的bug,ES性能体现在在分布式计算中,一个节点是不足以测试出其性能,一个生产系统至少在三个节点以上. ES集群节点规 ...

  9. Android性能优化系列之App启动优化

    Android性能优化系列之布局优化 Android性能优化系列之内存优化 Android性能优化系列之apk瘦身 应用的启动速度缓慢是我们在开发过程中常常会遇到的问题,比方启动缓慢导致的黑屏.白屏问 ...

随机推荐

  1. MVC5 网站开发之九 网站设置

    网站配置一般用来保存网站的一些设置,写在配置文件中比写在数据库中要合适一下,因为配置文件本身带有缓存,随网站启动读入缓存中,速度更快,而保存在数据库中要单独为一条记录创建一个表,结构不够清晰,而且读写 ...

  2. C#基础(1)

    .NET的开发方向,有三种: ① 桌面开发系统,即WinForm: ② Internet应用程序,ASP.NET,其实也就是网站开发: ③ 手机开发,WP7,Windows Phone 7. .NET ...

  3. activity的横屏和竖屏设置

    主要在清单文件这样配置: <application android:allowBackup="true" android:icon="@drawable/ic_la ...

  4. hdu_5884_Sort(二分+单调队列)

    题目链接:hdu_5884_Sort 题意: 有n个数,每个数有个值,现在你可以选择每次K个数合并,合并的消耗为这K个数的权值和,问在合并为只有1个数的时候,总消耗不超过T的情况下,最小的K是多少 题 ...

  5. chapter 14_1 环境

    Lua将其所有的全局变量保存在一个常规的table中,称为“global environment”. Lua将环境table自身保存在一个全局变量_G中,_G._G等于 _G . 比如下面的代码打印出 ...

  6. C# MongoDB 查询,分组,聚合,排序,条件,分页

    先下载个C#的驱动.MongoDB提供各种主流与非主流预言的开发驱动. C# Driver 下载地址:这里 CSharp Driver Tutorial:这里 下载文件安装或者解压缩包 如果您是安装, ...

  7. OpenCV——老照片效果

    // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...

  8. RabbitMQ 安装 Your installed version of Erlang (6.2) is too old. Please install a more recent version.

    windows安装RabbitMQ时在安装完Erlang语言开发包后,再安装RabbitMQ时报错: Your installed version of Erlang (6.2) is too old ...

  9. for update 与where current of的问题

    在刚学oracle时一直不明白for update 的作用,今天考试又遇到郁闷半天,所以加以整理. 一: 1>首先for update是对表的行进行锁定.锁定就好比我们学java Thread那 ...

  10. nginx 添加response响应头

    硬添