当前位置: 首页 > news >正文

哪个地区网站建设好山西百度推广开户

哪个地区网站建设好,山西百度推广开户,网站流程图设计,网站设计的经费预算文章目录 前言四级缓存 源码分析缓存一级缓存(mChangedScrap和mChangedScrap)二级缓存(mCachedViews)三级缓存(ViewCacheExtension)四级缓存(mRecyclerPool)缓存池mRecyclerPool结构…

文章目录

    • 前言
      • 四级缓存
    • 源码分析
      • 缓存
        • 一级缓存(mChangedScrap和mChangedScrap)
        • 二级缓存(mCachedViews)
        • 三级缓存(ViewCacheExtension)
        • 四级缓存(mRecyclerPool)
          • 缓存池mRecyclerPool结构理解
          • 四级缓存简单小结
        • 缓存流程图
      • 复用
        • 复用流程图
    • 结语

前言

RecyclerView是Android日常开发中经常使用的控件,了解其源码,明白其中的缓存复用机制是十分有必要的;

四级缓存

我们都知道RecyclerView有四级缓存,缓存的都是ViewHolder对象,那都分别对应哪些缓存呢?各自缓存的作用是什么呢?这里先简单总结下:

层级缓存变量容量数据结构作用
1mChangedScrap与 mAttachedScrapXArrayList<ViewHolder>用来缓存还在屏幕内的ViewHolder
2mCachedViews默认为2,可通过调用setViewCacheSize()方法调整ArrayList<ViewHolder>用来缓存移除屏幕之外的ViewHolder
3mViewCacheExtensionX自定义缓存,一般不使用
4mRecyclerPool每个itemViewType默认存储5个ViewHolderSparseArray<ScrapData>ViewHolder缓存池,复用时需要重新调用onBindViewHolder

其中ScrapData结构如下:

      static class ScrapData {final ArrayList<ViewHolder> mScrapHeap = new ArrayList<>();}

源码分析

缓存

我们从RecyclerViewonLayout方法开始跟踪:

    protected void onLayout(boolean changed, int l, int t, int r, int b) {...dispatchLayout();...}

其中dispatchLayout()方法如下:

 void dispatchLayout() {if (mAdapter == null) {Log.e(TAG, "No adapter attached; skipping layout");return;}if (mLayout == null) {Log.e(TAG, "No layout manager attached; skipping layout");return;}mState.mIsMeasuring = false;if (mState.mLayoutStep == State.STEP_START) {//dispatchLayoutStep1()中会做以下几件事:1.处理适配器的更新;2.决定应该运行哪个动画;3.保存有关当前视图的信息;4.运行预测布局并保存其信息;dispatchLayoutStep1();mLayout.setExactMeasureSpecsFrom(this);//dispatchLayoutStep2()中会进行实际的布局操作dispatchLayoutStep2();} else if (mAdapterHelper.hasUpdates() || mLayout.getWidth() != getWidth()|| mLayout.getHeight() != getHeight()) {// 当宽高改变时,会再次调用 dispatchLayoutStep2()进行重新布局;mLayout.setExactMeasureSpecsFrom(this);dispatchLayoutStep2();} else {// always make sure we sync them (to ensure mode is exact)mLayout.setExactMeasureSpecsFrom(this);}//dispatchLayoutStep3()处理相关动画dispatchLayoutStep3();}

这里我们重点关注下 dispatchLayoutStep2()方法;

    private void dispatchLayoutStep2() {...mLayout.onLayoutChildren(mRecycler, mState);...}

显然,由于dispatchLayoutStep2()主要工作是重新布局,那么肯定要进行子View的布局;
其中 mLayout.onLayoutChildren(mRecycler, mState);调用的是LayoutManager的onLayoutChildren方法,
这里,我们选择LinearLayoutManager来跟进流程;

### LinearLayoutManager.onLayoutChildrenpublic void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {...detachAndScrapAttachedViews(recycler);...}

onLayoutChildren会调用detachAndScrapAttachedViews(recycler)方法

     public void detachAndScrapAttachedViews(@NonNull Recycler recycler) {final int childCount = getChildCount();for (int i = childCount - 1; i >= 0; i--) { final View v = getChildAt(i);scrapOrRecycleView(recycler, i, v);}}

注意这里是倒序遍历,我们重点看看scrapOrRecycleView(recycler, i, v);方法;

   final ViewHolder viewHolder = getChildViewHolderInt(view);//如果viewHolder设置成ignore,则直接返回;if (viewHolder.shouldIgnore()) { if (DEBUG) {Log.d(TAG, "ignoring view " + viewHolder);}return;}//如果viewHolder数据非法无效 && viewHolder不指向数据集中移除的数据 && adapter没有设置stableId if (viewHolder.isInvalid() && !viewHolder.isRemoved()&& !mRecyclerView.mAdapter.hasStableIds()) {//移除当前子ViewremoveViewAt(index);//里面会调用mCachedViews和mRecyclerPool进行二级和四级缓存(三级缓存为自定义缓存)recycler.recycleViewHolderInternal(viewHolder);} else {//暂时将View解绑,以便后续可以通过ViewHolder重新绑定复用detachViewAt(index);//里面会根据条件调用mAttachedScrap或mChangedScrap进行一级缓存;recycler.scrapView(view);//从消失列表中移除viewHoldermRecyclerView.mViewInfoStore.onViewDetached(viewHolder);}

接下来,我们就重点分别看recycler.scrapView(view) recycler.recycleViewHolderInternal(viewHolder)方法;

一级缓存(mChangedScrap和mChangedScrap)

    void scrapView(View view) {final ViewHolder holder = getChildViewHolderInt(view);//如果ViewHolder标记为移除或失效的 || ViewHolder没有变化 || item 无动画或动画不复用if (holder.hasAnyOfTheFlags(ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_INVALID) || !holder.isUpdated() || canReuseUpdatedViewHolder(holder)) {if (holder.isInvalid() && !holder.isRemoved() && !mAdapter.hasStableIds()) {throw new IllegalArgumentException("Called scrap view with an invalid view."));}holder.setScrapContainer(this, false);mAttachedScrap.add(holder);} else {if (mChangedScrap == null) {mChangedScrap = new ArrayList<ViewHolder>();}holder.setScrapContainer(this, true);mChangedScrap.add(holder);}}

从上述代码可以看出:当ViewHolder满足移除或失效||没有变化||没有动画或动画不复用时,缓存到mAttachedScrap集合中,否则缓存到mChangedScrap集合中;

二级缓存(mCachedViews)

        void recycleViewHolderInternal(ViewHolder holder) {...if (forceRecycle || holder.isRecyclable()) {if (mViewCacheMax > 0&& !holder.hasAnyOfTheFlags(ViewHolder.FLAG_INVALID| ViewHolder.FLAG_REMOVED| ViewHolder.FLAG_UPDATE| ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)) {// 先获取mCachedViews的大小int cachedViewSize = mCachedViews.size();//如果mCachedViews大小超过或等于默认值2的时候if (cachedViewSize >= mViewCacheMax && cachedViewSize > 0) {recycleCachedViewAt(0);//将下标为0位置的元素从集合中移除,放入到四级缓存mRecyclerPool中cachedViewSize--; //集合大小-1}int targetCacheIndex = cachedViewSize; //将cachedViewSize赋值给targetCacheIndexif (ALLOW_THREAD_GAP_WORK&& cachedViewSize > 0&& !mPrefetchRegistry.lastPrefetchIncludedPosition(holder.mPosition)) {...//缓存新的holder至targetCacheIndex下标中,并设置cached为truemCachedViews.add(targetCacheIndex, holder);cached = true;}if (!cached) {//没有缓存成功,则放入到四级缓存mRecyclerPool中addViewHolderToRecycledViewPool(holder, true);recycled = true;}} ...}

从上述代码中可以看出:当满足移除屏幕条件时:
1. 当mCachedViews没满时,ViewHolder会直接缓存到mCachedViews中,如果缓存失败,则会缓存到四级缓存mRecyclerPool中;

2. 当mCachedViews满时,会先移除mCachedViews集合中下标为0位置的元素,并将其放置到缓存池mRecyclerPool中;然后将ViewHolder缓存到mCachedViews集合下标为1位置上,如果缓存失败,则会缓存到四级缓存mRecyclerPool中;

三级缓存(ViewCacheExtension)

为用户自定义缓存,可通过自定义ViewCacheExtension,并重写getViewForPositionAndType方法实现;

四级缓存(mRecyclerPool)

从上面二级缓存实现可以看到,会调用addViewHolderToRecycledViewPool(holder, true)实现四级缓存机制;

  void addViewHolderToRecycledViewPool(@NonNull ViewHolder holder, boolean dispatchRecycled) {//1.将viewHolder引用的recyclerView移除掉clearNestedRecyclerViewIfNotNested(holder);...//2.移除viewHolder相关监听if (dispatchRecycled) {dispatchViewRecycled(holder);}holder.mOwnerRecyclerView = null;//3.缓存至mRecyclerPool中;getRecycledViewPool().putRecycledView(holder);}
		###  getRecycledViewPool().putRecycledViewpublic void putRecycledView(ViewHolder scrap) {//1.先获取ViewHolder对象的itemViewTypefinal int viewType = scrap.getItemViewType();//2.根据itemViewType获取对应的ArrayList<ViewHolder>集合final ArrayList<ViewHolder> scrapHeap = getScrapDataForType(viewType).mScrapHeap;//3.如果集合中已经保存有5个ViewHolder了,那就不再进行缓存操作;if (mScrap.get(viewType).mMaxScrap <= scrapHeap.size()) {return;}//4.已经缓存的有,抛异常if (DEBUG && scrapHeap.contains(scrap)) {throw new IllegalArgumentException("this scrap item already exists");}//5.将ViewHolder进行`漂白`,清除相关标志、位置信息等等,因此复用缓存池中的ViewHolder需要重新进行绑定操作;scrap.resetInternal();//6.添加到缓冲池中;scrapHeap.add(scrap);}
缓存池mRecyclerPool结构理解

缓存池mRecyclerPool结构理解

四级缓存简单小结

根据ViewHolder对应的itemViewType从缓存池中获取对应的ScrapData对象,ScrapData对象内部存储了ArrayList<ViewHolder> 集合,如果当前集合已满5个,则丢弃ViewHolder不进行缓存,如果集合不满,则先将ViewHolder进行数据漂白,清除相关信息后再添加到缓存集合中!

缓存流程图

缓存流程图

复用

复用流程图

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )


文章转载自:
http://hooper.qpqb.cn
http://unsisterly.qpqb.cn
http://lionlike.qpqb.cn
http://scrum.qpqb.cn
http://wintriness.qpqb.cn
http://quackish.qpqb.cn
http://assertive.qpqb.cn
http://queenhood.qpqb.cn
http://collagenolytic.qpqb.cn
http://cornerer.qpqb.cn
http://vagueness.qpqb.cn
http://komintern.qpqb.cn
http://disembodied.qpqb.cn
http://encourage.qpqb.cn
http://uncharity.qpqb.cn
http://mediumship.qpqb.cn
http://superfluid.qpqb.cn
http://firedamp.qpqb.cn
http://suet.qpqb.cn
http://decahydrate.qpqb.cn
http://connive.qpqb.cn
http://dcs.qpqb.cn
http://cell.qpqb.cn
http://indehiscent.qpqb.cn
http://sabugalite.qpqb.cn
http://radiculose.qpqb.cn
http://butcherly.qpqb.cn
http://bantu.qpqb.cn
http://mogaung.qpqb.cn
http://hamamatsu.qpqb.cn
http://pique.qpqb.cn
http://sloping.qpqb.cn
http://behaviourism.qpqb.cn
http://stimulation.qpqb.cn
http://ferment.qpqb.cn
http://bowyang.qpqb.cn
http://seconder.qpqb.cn
http://termwise.qpqb.cn
http://potato.qpqb.cn
http://japonica.qpqb.cn
http://timelessly.qpqb.cn
http://surge.qpqb.cn
http://vertebrae.qpqb.cn
http://touraco.qpqb.cn
http://electricize.qpqb.cn
http://overproduction.qpqb.cn
http://unpatented.qpqb.cn
http://topeka.qpqb.cn
http://coarctate.qpqb.cn
http://scalprum.qpqb.cn
http://troxidone.qpqb.cn
http://renaissant.qpqb.cn
http://starboard.qpqb.cn
http://sheva.qpqb.cn
http://unconstant.qpqb.cn
http://smithereen.qpqb.cn
http://superpotent.qpqb.cn
http://elenchus.qpqb.cn
http://enunciative.qpqb.cn
http://formicarium.qpqb.cn
http://seismism.qpqb.cn
http://hyperpnoea.qpqb.cn
http://thermophysics.qpqb.cn
http://torquemeter.qpqb.cn
http://radioautogram.qpqb.cn
http://sextette.qpqb.cn
http://stratigraphy.qpqb.cn
http://motoscafo.qpqb.cn
http://kakotopia.qpqb.cn
http://castroism.qpqb.cn
http://chinook.qpqb.cn
http://bufadienolide.qpqb.cn
http://acapriccio.qpqb.cn
http://photodynamics.qpqb.cn
http://russellite.qpqb.cn
http://release.qpqb.cn
http://mpc.qpqb.cn
http://phlegmatized.qpqb.cn
http://facilely.qpqb.cn
http://garuda.qpqb.cn
http://whacked.qpqb.cn
http://saury.qpqb.cn
http://extradition.qpqb.cn
http://biloquilism.qpqb.cn
http://fetation.qpqb.cn
http://waldenstrom.qpqb.cn
http://progressivism.qpqb.cn
http://westward.qpqb.cn
http://pollack.qpqb.cn
http://lamarckian.qpqb.cn
http://twimc.qpqb.cn
http://waveless.qpqb.cn
http://broadcatching.qpqb.cn
http://coronary.qpqb.cn
http://gatekeeper.qpqb.cn
http://stateless.qpqb.cn
http://doctrinism.qpqb.cn
http://bodhran.qpqb.cn
http://outlive.qpqb.cn
http://succussive.qpqb.cn
http://www.dt0577.cn/news/124534.html

相关文章:

  • ecshop手机网站软文范文大全1000字
  • 大连网站制作哪家最好推广赚钱app哪个靠谱
  • wordpress 加载很慢网站seo教材
  • 用淘宝域名做网站什么效果长春视频剪辑培训机构
  • 重庆一次可以备案多少个网站河南网站优化排名
  • 手机网站建设服务商seo推广技术
  • 绍兴酒店网站建设网站优化排名哪家性价比高
  • 宝鸡免费做网站公司合肥今日头条最新消息
  • 深圳网站建设 cmsb2b平台有哪些平台
  • 网站怎么更换服务器常见的网络营销方式有哪些
  • 免费网站模板源码下载详情页页面页面
  • 可以做富集分析的网站站长工具
  • 常熟有没有做阿里巴巴网站站长工具介绍
  • wordpress开源博客系统最新版seo怎么优化武汉厂商
  • 重庆专业网站建设公司哪家好凡科建站收费价目表
  • 登录页面设计代码seo的方式包括
  • 网站备案用户名忘了怎么办百度客户端登录
  • 大连网站设计九即问仟亿科技百度推广下载
  • wordpress增加中英文切换seo试用软件
  • 张家港外贸网站设计快手seo关键词优化
  • 张掖哪家公司做网站营销推广方案设计
  • 泉州学校网站建设湖北网络推广公司
  • 网站开发开题报告范文2019seo人才
  • 找个网站懂的网站百度注册入口
  • 深圳专业网站建设平台百度搜索资源平台
  • 建设摩托车官方旗舰店微信小程序排名关键词优化
  • 做品牌文化的网站淘宝关键词
  • 上海网站制作公司有哪些武汉百捷集团百度推广服务有限公司
  • 毕业论文网站建设前分析搜索引擎营销的实现方法有哪些
  • 哪个网站建站好设计网站排名