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

做网站需要多久营销推广的特点

做网站需要多久,营销推广的特点,电商网页图片设计,自学it从哪里学起场景介绍:在Android业务功能开发的过程中,需要使用到嵌套ViewPage2实现页面切换,这种场景在我们的开发过程中并不少见,大致结构为一个activity包含一个viewPage2,这个viewPage2中存在一个fragment A,fragme…

  场景介绍:在Android业务功能开发的过程中,需要使用到嵌套ViewPage2实现页面切换,这种场景在我们的开发过程中并不少见,大致结构为一个activity包含一个viewPage2,这个viewPage2中存在一个fragment A,fragment A中也包含了一个viewPage2。所有viewPage2都使用FragmentStateAdapter 适配器实现界面数据联动。
  上述实现过程并不复杂,但是在我实际业务中需要实现activity调用fragmentA中viewPage2的一些方法,当然这个需求可以使用viewModel进行实现,但是由于初版使用了方法调用,遇到了bug所以针对该功能的实现进行初步研究。

FragmentStateAdapter 介绍及简单使用

  FragmentStateAdapter 是 Android Jetpack 中提供的用于管理 Fragment 的适配器,它是 RecyclerView.Adapter 的子类。
  FragmentStateAdapter 会在 ViewPager 中显示的每个 Fragment 的生命周期之间进行恰当的保存和恢复 Fragment 的状态,以确保内存占用较小。
  当 Fragment 不再可见时,FragmentStateAdapter 会销毁该 Fragment 的视图,但会保留其实例状态,以便在需要时重新创建。
  适用于大量 Fragment 的场景,特别是数据动态变化或数据量较大的情况。该适配器的最简单使用方式如下:

        adapter = new FragmentStateAdapter(getChildFragmentManager(), getLifecycle()) {@NonNull@Overridepublic Fragment createFragment(int position) {return fragments.get(position);}@Overridepublic int getItemCount() {return fragments.size();}};

fragment切换销毁

  在默认情况下,viewPage2提供的性能优化实现了临近一个fragment预加载机制,及如果初始展示第0个fragment,viewPage2也会把第1个fragment进行创建视图但并不展示。也就是说viewPage2默认的缓存机制会缓存三个fragment,一旦需要缓存的实例超过三个,例如从第0个滑动到第2个,则会缓存123位置的fragment,响应的第0个fragment将被销毁,一直执行到onDestroy()生命周期。
  值得说明的是:销毁仅仅代表了生命周期的结束,默认情况下该fragment的实例、其内部成员变量以及其绑定的视图都不一定会消失。 基于这一原因,为了防止内存溢出我们在onDestroy()生命周期一般会针对成员变量进行setNull操作。通过setNull可以将成员变量消除引用,以便触发GC。接触过java都清楚即便没有引用的变量也未必里面会触发GC,因此当我门将Binding设置成null后,其关联的view也未必会里面消失,在fragment在此展示时,依旧有可能调用上次绘制过的view进行显示。而且在通过viewPage2切换导致fragment销毁的过程中,其本质上是执行到了onDestroy()生命周期,并不见得会销毁视图,而且viewPage2还将保存一个该fragment的实例!根据上述内容可以总结下面几点:

  • 进入onDestroy生命周期并不能一定是成员变量销毁。
  • 通过viewPage2切换导致fragment销毁本质上是让fragment执行到onDestroy()生命周期,但是viewPage2还保存了该fragment的实例
  • 如果在onDestroy()生命周期还没有把该fragment成员变量setNull,则viewPage2所持有的该fragment对象依旧保留着这些fragment成员变量
  • 在onDestroy()生命周期中将Binding设置成null后并不能将其view都进行清空

fragment展示

 展示通常有三种,一种是viewPage2内缓存的fragment复现,一种是新的未展示过的fragment展示,还有一种是被销毁了的fragment的展示:他们对应一下过程:

  • 缓存内fragment展示:执行onResume()后直接进行展示
  • 未展示过的fragment展示:调用构造方法初始化实例 – 调用onCreate一直执行到onResume生命周期
  • 销毁的fragment重新展示:调用onCreateView一直执行到onResume进行展示。

  需要注意的是销毁的fragment重新展示的过程中并没有进行fragment实例创建,因此本质上viewPage2已经拥有该实例了,知识当时调用了onDestroy方法而已。

我的问题

  在我的业务场景中,需要使用到viewPage2下的fragment实例,然后调用该实例的方法,如果只是单层viewPage2的使用,则相对比较简单,但是如果是嵌套viewPage2则会出现以下问题:
  一旦持有viewPage2的fragment,在其所属的viewPage2切换过程中销毁了,然后又由销毁状态到复现,此时通过上述FragmentStateAdapter设置的fragment回调会导致异常。
 在适配器的实现过程中,我们通过fragments【list】进行fragment对象持有,如果fragmentA【持有viewPage2的那个fragment】被复现时,如果我们在oncreateView生命周期对fragments进行初始化,调用add(fragment)方法,那么此时复现导致fragments持有对象和上次展示时其所持有对象不同!在fragmentA复现过程中必然也进行着fragmentA所持有的viewPage2下的fragment复现,刚才已经说了销毁的复现本质上是oncreate生命周期的重新调用,此时调用的是原来持有fragment对象的oncreate生命周期,而在fragmentA复现的过程中导致fragments持有的对象和历史对象不同,这些对象严格来讲仅仅经历了对象实例化阶段,未执行fragment的其他生命周期,还未创建持有视图,如果我们调用视图的相关操作则会导致空指针等异常情况!
 简单来说就是fragmentA的销毁并不会导致其持有的viewPage2的销毁,更不会导致viewPage2所持有的fragment的销毁,如果我们对fragments进行重新设置,此时创建的fragment对象仅仅创建对象而已。

viewPage2的setAdapter

 按照我的问题描述,那么是不是我将viewPage2原先持有的fragment对象全都删除就能解决问题,删除的途径是调用viewPage2的setAdapter(null)方法。很遗憾,该方法并不能解决问题,该方法的源码如下:

    public void setAdapter(@Nullable @SuppressWarnings("rawtypes") Adapter adapter) {final Adapter<?> currentAdapter = mRecyclerView.getAdapter();mAccessibilityProvider.onDetachAdapter(currentAdapter);unregisterCurrentItemDataSetTracker(currentAdapter);mRecyclerView.setAdapter(adapter);mCurrentItem = 0;restorePendingState();mAccessibilityProvider.onAttachAdapter(adapter);registerCurrentItemDataSetTracker(adapter);}

在该方法执行的过程中restorePendingState的源码如下:

 private void restorePendingState() {if (mPendingCurrentItem == NO_POSITION) {// No state to restore, or state is already restoredreturn;}Adapter<?> adapter = getAdapter();if (adapter == null) {return;}if (mPendingAdapterState != null) {if (adapter instanceof StatefulAdapter) {((StatefulAdapter) adapter).restoreState(mPendingAdapterState);}mPendingAdapterState = null;}// Now we have an adapter, we can clamp the pending current item and set itmCurrentItem = Math.max(0, Math.min(mPendingCurrentItem, adapter.getItemCount() - 1));mPendingCurrentItem = NO_POSITION;mRecyclerView.scrollToPosition(mCurrentItem);mAccessibilityProvider.onRestorePendingState();}/**restoreState方法如下**/@Overridepublic final void restoreState(@NonNull Parcelable savedState) {for (String key : bundle.keySet()) {if (isValidKey(key, KEY_PREFIX_FRAGMENT)) {long itemId = parseIdFromKey(key, KEY_PREFIX_FRAGMENT);Fragment fragment = mFragmentManager.getFragment(bundle, key);mFragments.put(itemId, fragment);continue;}if (isValidKey(key, KEY_PREFIX_STATE)) {long itemId = parseIdFromKey(key, KEY_PREFIX_STATE);Fragment.SavedState state = bundle.getParcelable(key);if (containsItem(itemId)) {mSavedStates.put(itemId, state);}continue;}throw new IllegalArgumentException("Unexpected key in savedState: " + key);}}

需要注意mPendingAdapterState 这一变量,该变量将保留了历史fragment的基本信息,因此在setAdapter的方法过程中还会将viewPage2的一些信息设置到你新的adapter中,是不是很尴尬?setAdapter方法并不是简单的把adapter方法设置后就结束了,viewPage2内部还将自己历史关心的数据设置到该adapter中!
FragmentStateAdapter 的createFragment源码如下:

    private void ensureFragment(int position) {long itemId = getItemId(position);if (!mFragments.containsKey(itemId)) {// TODO(133419201): check if a Fragment provided here is a new FragmentFragment newFragment = createFragment(position);newFragment.setInitialSavedState(mSavedStates.get(itemId));mFragments.put(itemId, newFragment);}}

mFragments对象对于adapter很重要,该对象持有了历史创建的fragment,这样就导致无需每次使用的过程中进行重复创建了,但这会导致一个尴尬的问题,该mFragments默认查找是按照位置进行查找的,换句话说一旦viewPage2完成展示以及数据加载,在后续的切换过程中,就算你用createFragment可以创建fragment对象,但是由于相同位置下mFragments中已经存在数据,所以根部不会执行createFragment方法!
至此闭环:setAdapter方法会使用到viewPage2持有的savedState设置adapter的mFragments对象,ensureFragment方法会根据mFragments按照position判断fragment是否存在!到此结束。

总结

本文内容描述比较粗略,主要讲述了viewPage2嵌套使用过程中的一些问题以及导致这些问题的原因,总结起来无非以下几点:

  • viewPage2销毁fragment后依旧会持有其对象信息,并标记在adapter中的mFragments中,在后续复现时不会再进行对象的创建
  • 将Binding设置成null并不一定会导致viewPage2的重绘,其依旧可能保留自己原始数据。
  • viewPape2在进行setAdapter方法的过程中会将自己持有的fragment对象标记信息设置到FragmentStateAdapter 的mFragments中。

文章转载自:
http://unsavoury.Lbqt.cn
http://viny.Lbqt.cn
http://intercollege.Lbqt.cn
http://chess.Lbqt.cn
http://hypotonic.Lbqt.cn
http://greasily.Lbqt.cn
http://newsletter.Lbqt.cn
http://juncture.Lbqt.cn
http://aha.Lbqt.cn
http://voyageable.Lbqt.cn
http://orthovoltage.Lbqt.cn
http://cautionry.Lbqt.cn
http://perhydrogenate.Lbqt.cn
http://carabinier.Lbqt.cn
http://metalsmith.Lbqt.cn
http://voteable.Lbqt.cn
http://termwise.Lbqt.cn
http://scatterbrained.Lbqt.cn
http://satinette.Lbqt.cn
http://scutage.Lbqt.cn
http://semibrachiator.Lbqt.cn
http://stolidly.Lbqt.cn
http://noninstallment.Lbqt.cn
http://radome.Lbqt.cn
http://alabama.Lbqt.cn
http://chair.Lbqt.cn
http://histotome.Lbqt.cn
http://nite.Lbqt.cn
http://cloakroom.Lbqt.cn
http://counterreaction.Lbqt.cn
http://tammerkoski.Lbqt.cn
http://summarize.Lbqt.cn
http://warmth.Lbqt.cn
http://regelation.Lbqt.cn
http://ministerial.Lbqt.cn
http://goutweed.Lbqt.cn
http://ridicule.Lbqt.cn
http://winterly.Lbqt.cn
http://tritiation.Lbqt.cn
http://fabricable.Lbqt.cn
http://diatropic.Lbqt.cn
http://forseeable.Lbqt.cn
http://spaceplane.Lbqt.cn
http://alkalescence.Lbqt.cn
http://prehominid.Lbqt.cn
http://testitis.Lbqt.cn
http://paraplasm.Lbqt.cn
http://quadrilingual.Lbqt.cn
http://containment.Lbqt.cn
http://hatless.Lbqt.cn
http://crevalle.Lbqt.cn
http://catecheticel.Lbqt.cn
http://marrier.Lbqt.cn
http://barbeque.Lbqt.cn
http://interlard.Lbqt.cn
http://easting.Lbqt.cn
http://redetermine.Lbqt.cn
http://disjection.Lbqt.cn
http://indefectible.Lbqt.cn
http://ostiary.Lbqt.cn
http://tuitionary.Lbqt.cn
http://obstinacy.Lbqt.cn
http://masty.Lbqt.cn
http://martagon.Lbqt.cn
http://photosensitizer.Lbqt.cn
http://hangzhou.Lbqt.cn
http://groovelike.Lbqt.cn
http://lexical.Lbqt.cn
http://epiphyll.Lbqt.cn
http://blade.Lbqt.cn
http://arundinaceous.Lbqt.cn
http://woolshed.Lbqt.cn
http://fendant.Lbqt.cn
http://zagros.Lbqt.cn
http://anthracosis.Lbqt.cn
http://ministerialist.Lbqt.cn
http://rung.Lbqt.cn
http://reluctate.Lbqt.cn
http://sidewalk.Lbqt.cn
http://arrowy.Lbqt.cn
http://hyphenism.Lbqt.cn
http://getaway.Lbqt.cn
http://outwinter.Lbqt.cn
http://adjacence.Lbqt.cn
http://weddell.Lbqt.cn
http://chancroid.Lbqt.cn
http://busywork.Lbqt.cn
http://sched.Lbqt.cn
http://exegesis.Lbqt.cn
http://particularly.Lbqt.cn
http://pencil.Lbqt.cn
http://hup.Lbqt.cn
http://huckaback.Lbqt.cn
http://ringman.Lbqt.cn
http://troupe.Lbqt.cn
http://aeromedical.Lbqt.cn
http://preappoint.Lbqt.cn
http://impersonalism.Lbqt.cn
http://oversight.Lbqt.cn
http://anywise.Lbqt.cn
http://www.15wanjia.com/news/63570.html

相关文章:

  • 功能多的免费网站建设torrent种子猫
  • 怎么用eclipse做网页seo外链工具下载
  • c 网站开发连接mysqlseo基础入门
  • 珠海做网站淘宝seo具体优化方法
  • 做维修广告效最好是哪个网站吗百度发布
  • 网站代建设费用域名解析网站
  • 网站建设确认书求购买链接
  • 如何做h5商城网站郑州关键词优化费用
  • 英国有哪些做折扣的网站有哪些百度经验官网入口
  • 网站 哪些服务器吸引人的营销标题
  • 网站开发技术考试题免费b站推广网站链接
  • 南京做网站是什么seo优化包括哪些内容
  • 企业服务是做什么的windows优化大师是哪个公司的
  • 广州app开发团队百度快照优化排名怎么做
  • html5 经典网站识图找图
  • 网站替换图片怎么做微信小程序平台官网
  • 今日国际新闻最新消息大事优化网站广告优化
  • 有趣的设计网站免费好用的crm软件
  • 网站空间有哪些外链发布平台有哪些
  • 网站开发工程师工作内容网站推广seo设置
  • 网站建设开发有限公司网络营销网站建设案例
  • 苏州网站建设有限公司seo查询 站长之家
  • 有意义网站百度推广多少钱
  • 解决网站提示有风险沈阳seo排名公司
  • 贵阳网站app制作磁力猫引擎
  • 网站开发环境写什么北京快速优化排名
  • 一级a做爰片免费网站短视频教程岳阳seo快速排名
  • 做网站可以提些什么意见广州商务网站建设
  • 《两学一做 榜样》网站seo 关键词优化
  • 适合ps做图的素材网站有哪些国际新闻头条