android:Listview和recycleview的内存优化原理
<p>吐槽:一直想写一篇完整的,能系统地介绍某个知识点的文章,但由于技术不够加上懒,只能仰望其他大神写出的非常优秀的文章,从中学习一二。今天看了hongyang大神写的关于recycleview的博客,获益良多啊!不过鸿神可能要全面解析这个控件,没那么多篇幅来写一些原理问题,所以我google了一番结合listview来介绍他们的优化原理(作为初学者,我仅凭自己理解去写这篇文章,如有错误,你来打我啊(开玩笑...),还是非常希望各位能及时帮我更正)</p> <p>首先我们来看下,没有优化过的listview中getView方法(因为是介绍原理问题,所有的代码就不贴上了,百度一大堆)</p> <pre> <code class="language-java">@Override public View getView(int position, View convertView, ViewGroup parent) { //listview_item里只有一个textview View view = View.inflate(MainActivity.this, R.layout.listview_item, null); //使用每一次都findviewById的方法来获得listview_item内部的组件 TextView tv_item = (TextView) view.findViewById(R.id.tv_item); tv_item.setText(list.get(position)); return view; }</code></pre> <p>当我们的item有十几个的时候,手机屏幕不足以完全显示(说iphone18的走开!!),所以我们要向上滑动以显示下面其他的item,但这时前面的item就会淡出屏幕,再向下滑动,又显示前面的item了,但你会发现,无论显示第一个item还是显示最后一个item,只要出现在屏幕上一次,就会调用一次getView来创建这个item。这无疑是很浪费内存的,所以就有下面的优化方案。</p> <pre> <code class="language-java">public View getView(int position, View convertView, ViewGroup parent) { View view; ViewHolder holder; // 判断convertView的状态,来达到复用效果 if (null == convertView) { // 如果convertView为空,则表示第一次显示该条目,需要创建一个view view = View.inflate(MainActivity.this, R.layout.listview_item, null); //新建一个viewholder对象 holder = new ViewHolder(); //将findviewbyID的结果赋值给holder对应的成员变量 holder.tvHolder = (TextView) view.findViewById(R.id.tv_item); // 将holder与view进行绑定 view.setTag(holder); } else { // 否则表示可以复用convertView view = convertView; holder = (ViewHolder) view.getTag(); } // 直接操作holder中的成员变量即可,不需要每次都findViewById holder.tvHolder.setText(list.get(position)); return view; }</code></pre> <p>convertView这个参数设计非常巧妙,是用来储存那些被你万恶的手指滑动导致淡出的item,当它为空,说明之前没有被创建过,所以就创建这个item,它不为空时,嘿嘿,说明是被淡出的item,之前有被创建,那就直接拿出来用就行啦。关于ViewHolder很多资料也有介绍,这里也不再赘述了。来看下图更有利于理解:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/dd3756ef6bf38e14b2e8d63c877b8c50.png"></p> <p>Paste_Image.png</p> <p>上面是ListView的。接下来我们来看下RecycleView:</p> <pre> <code class="language-java">package com.example.q_recycler; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import java.util.List; /** * Created by 强强 on 2017/2/6. */ public class MyRecycleviewAdapter extends RecyclerView.Adapter<MyRecycleviewAdapter.ViewHolder>{ List<String> list; public MyRecycleviewAdapter(List<String> list){ this.list=list; } @Override public MyRecycleviewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.id_num,parent,false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.tv.setText(list.get(position)); } @Override public int getItemCount() { if(list!=null) return list.size(); else return 0; } class ViewHolder extends RecyclerView.ViewHolder { public TextView tv; public ViewHolder(View itemView) { super(itemView); tv= (TextView) itemView.findViewById(R.id.id_num); } } }</code></pre> <p>RecycleView作为ListView的升级版,自然有它的优势,抛弃那n多的功能(被鸿神称为艺术般的控件),它的内存优化也是独到的哦。</p> <p>我的理解是:RecycleView提供了一个缓存机制,当一个item没有被创建时,就会调用onCreateViewHolder的方法创建这个item,同时也放入到缓存中,以ViewHolder的形式返回,当要显示item时,就会在缓存中寻找有没有创建过这个item,如果创建了的话就直接调用onBindViewHolder方法进行渲染显示。这里也避免重复创建item了,可见,它们的优化原理是相差无几的,结合起来更能让人理解。</p> <p> </p> <p> </p> <p> </p> <p>来自:http://www.jianshu.com/p/3b391cb69c1b</p> <p> </p>
本文由用户 deoy1644 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
转载本站原创文章,请注明出处,并保留原始链接、图片水印。
本站是一个以用户分享为主的开源技术平台,欢迎各类分享!