范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

字节跳动一面之Glide生命周期管理面试总结

  本文通过在字节面试遇到的问题总结而出,如有不对的地方,请及时批评指正。篇幅较长,请耐心阅读。如果您想了解其他框架源码,欢迎评论区留言!
  篇幅较长,请耐心阅读[玫瑰]
  简介
  Glide是一个优秀的图片加载框架,支持多种数据源,功能强大,性能高。如图所示:
  使用步骤
  1.在build.gradle中添加glide引用implementation "com.github.bumptech.glide:glide:4.12.0"
  2.使用glide加载图片Glide.with(this).load(BASE_PIC_URL).into(img_user)源码分析设计模式1.单例模式
  Glide使用了单例设计模式,通过双重校验锁机制不仅保证了Glide对象的全局单例,而且解决了多线程环境下的并发安全问题。2.工厂设计模式
  Glide内部的创建RequestManager对象时使用了工厂设计模式,通过定义RequestManagerFactory抽象接口,让其子类创建RequestManager对象,隐藏其内部创建逻辑。3.建造者设计模式
  Glide使用了静态类GlideBuilder构建Glide对象,将Glide的各种属性封装到GlideBuilder中,根据不同的属性设置构建不同功能的Glide对象。简化Glide的构建过程。生命周期绑定主线程中使用
  1 .Glide使用With方法传入所需要的上下文,主线程中一般传context,fragment,activity来实现对生命周期的绑定。public static RequestManager with(@NonNull Context context)  public static RequestManager with(@NonNull Activity activity)  public static RequestManager with(@NonNull Fragment fragment)  public static RequestManager with(@NonNull FragmentActivity activity)
  2 .下面以activity为例,参数传入activity。 public static RequestManager with(@NonNull Activity activity) {     return getRetriever(activity).get(activity);   }
  3 .通过调用RequestManagerRetriever的get方法,传入activity参数返回RequestManager对象。RequestManager主要负责管理Glide的请求和启动。  @NonNull   public RequestManager get(@NonNull Activity activity) {       //判断是否是后台线程     if (Util.isOnBackgroundThread()) {       return get(activity.getApplicationContext());     } else if (activity instanceof FragmentActivity) {       return get((FragmentActivity) activity);     } else {       //判断当前activity没有被销毁,否则抛出异常         assertNotDestroyed(activity);       frameWaiter.registerSelf(activity);       //获取activity中的FragmentManager        android.app.FragmentManager fm = activity.getFragmentManager();       //通过fragmentGet方法 ,创建并返回 RequestManager       return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));     }   }
  RequestManagerRetriever的get方法中根据传入的参数不同,使用Util.isOnBackgroundThread判断子线程和主线程分别进行不同的处理。主线程中最终都是调用fragmentGet方法。注意,由于这里的参数是activity,获取的是fragmentManager,如果传入的是fragment,则获取的childFragmentManager.
  4 .fragmentGet方法主要是通过RequestManagerFragment来获取RequestManager,如果没有获取到,则通过工厂模式进行创建。同时传入fragment的getGlideLifecycle。这个lifecycle是重点,需要注意。private RequestManager fragmentGet(       @NonNull Context context,       @NonNull android.app.FragmentManager fm,       @Nullable android.app.Fragment parentHint,       boolean isParentVisible) {     //通过fragmentManager获取RequestManagerFragment     RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);     //获取RequestManagerFragment中的requestManager     RequestManager requestManager = current.getRequestManager();     //判断requestManager     if (requestManager == null) {     //如果requestManager为空,则通过工厂设计模式创建出requestManager        Glide glide = Glide.get(context);       requestManager =           factory.build(               glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);       //如果activity显示出来,则执行requestManager的onStart方法                if (isParentVisible) {         requestManager.onStart();       }       current.setRequestManager(requestManager);     }     return requestManager;   }
  5 .创建RequestManagerFragment,这里创建一个空白页面的RequestManagerFragment并且绑定到当前activity中。@NonNull   private RequestManagerFragment getRequestManagerFragment(       @NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint) {       //通过tag获取fragmentManager中保存的fragment       RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);     if (current == null) {        //如果获取不到,则进一步通过 pendingRequestManagerFragments Map中获取       current = pendingRequestManagerFragments.get(fm);       if (current == null) {         //如果还是获取不到,则进行创建           current = new RequestManagerFragment();         current.setParentFragmentHint(parentHint);          //同时保存到map中          pendingRequestManagerFragments.put(fm, current);          //然后添加到当前activity中          fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();         //将这个添加动作通过handler发送给系统处理           handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();       }     }     return current;   }
  6 .RequestManagerFragment的构造函数创建了ActivityFragmentLifecycle用来监听RequestManagerFragment的生命周期 onStart(),onStop(),onDestroy() 。public SupportRequestManagerFragment() {     this(new ActivityFragmentLifecycle());  } public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {     this.lifecycle = lifecycle;   }  @Override   public void onStart() {     super.onStart();     lifecycle.onStart();   }    @Override   public void onStop() {     super.onStop();     lifecycle.onStop();   }    @Override   public void onDestroy() {     super.onDestroy();     lifecycle.onDestroy();   }
  最后在fragmentGet方法中将ActivityFragmentLifecycle通过工厂设计模式传给RequestManager并返回。
  7 .ActivityFragmentLifecycle继承于Lifecycle接口。 @Override   public void addListener(@NonNull LifecycleListener listener) {      //所有的监听者都添加监听     lifecycleListeners.add(listener);     //根据不同的生命周期进行处理      if (isDestroyed) {       listener.onDestroy();     } else if (isStarted) {       listener.onStart();     } else {       listener.onStop();     }   }    @Override   public void removeListener(@NonNull LifecycleListener listener) {       //移除所有监听     lifecycleListeners.remove(listener);   }    void onStart() {     //只添加一次监听       isStarted = true;      //同步所有生命周期       for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {       lifecycleListener.onStart();     }   }    void onStop() {     isStarted = false;      //同步所有生命周期        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {       lifecycleListener.onStop();     }   }    void onDestroy() {     isDestroyed = true;      //同步所有生命周期        for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {       lifecycleListener.onDestroy();     }   }
  8 .RequestManager拿到这个lifecycle,进行绑定监听RequestManagerFragment生命周期。 RequestManager(       Glide glide,       Lifecycle lifecycle,       RequestManagerTreeNode treeNode,       RequestTracker requestTracker,       ConnectivityMonitorFactory factory,       Context context) {     this.glide = glide;     this.lifecycle = lifecycle;     this.treeNode = treeNode;     this.requestTracker = requestTracker;     this.context = context;      ..)     ...........................      //判断是否是后台线程         if (Util.isOnBackgroundThread()) {       Util.postOnUiThread(addSelfToLifecycle);     } else {       //添加lifecycle监听          lifecycle.addListener(this);     }     lifecycle.addListener(connectivityMonitor);     ..............   }
  9 .通过生命周期的绑定处理对应的业务逻辑和资源释放等功能。 public synchronized void onStart() {     //开始请求      resumeRequests();     targetTracker.onStart();   }   @Override   public synchronized void onStop() {   //开始停止     pauseRequests();     targetTracker.onStop();   }   @Override   public synchronized void onDestroy() {     targetTracker.onDestroy();      //释放资源       targetTracker.clear();     requestTracker.clearRequests();     lifecycle.removeListener(this);     lifecycle.removeListener(connectivityMonitor);     Util.removeCallbacksOnUiThread(addSelfToLifecycle);     glide.unregisterRequestManager(this);   }
  总结如下图所示:
  Glide在主线程中使用时,通过创建一个空白的fragment添加到当前Activity/Fragment中,用来监听当前页面的生命周期变化,进行图片的显示或资源的释放。子线程中使用
  1 . Glide在子线程中使用只能传入applicationContext。public static RequestManager with(@NonNull Context context)
  2 .通过调用RequestManagerRetriever的get方法,传入activity参数返回RequestManager对象。RequestManager主要负责管理Glide的请求和启动。public RequestManager get(@NonNull Context context) {     if (context == null) {       throw new IllegalArgumentException("You cannot start a load on a null Context");     } else if (Util.isOnMainThread() && !(context instanceof Application)) {       if (context instanceof FragmentActivity) {         return get((FragmentActivity) context);       } else if (context instanceof Activity) {         return get((Activity) context);       } else if (context instanceof ContextWrapper              && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {         return get(((ContextWrapper) context).getBaseContext());       }     }     //子线程返回applicationManager     return getApplicationManager(context);   }
  3 .在getApplicationManager方法中通过双重校验锁的单例方式返回applicationManager,applicationManager的创建使用了工厂设计模式,隐藏了applicationManager的内部创建细节。 @NonNull   private RequestManager getApplicationManager(@NonNull Context context) {     if (applicationManager == null) {       synchronized (this) {         if (applicationManager == null) {           Glide glide = Glide.get(context.getApplicationContext());           applicationManager =               factory.build(                   glide,                   new ApplicationLifecycle(),                   new EmptyRequestManagerTreeNode(),                   context.getApplicationContext());         }       }     }      return applicationManager;   }
  4 .getApplicationManager创建applicationManager时传入了ApplicationLifecycle作为生命周期监听。 RequestManager(       Glide glide,       Lifecycle lifecycle,       RequestManagerTreeNode treeNode,       RequestTracker requestTracker,       ConnectivityMonitorFactory factory,       Context context) {     this.glide = glide;     this.lifecycle = lifecycle;     this.treeNode = treeNode;     this.requestTracker = requestTracker;     this.context = context;     .............      //如果是子线程,通过使用Handler切换到主线程     if (Util.isOnBackgroundThread()) {       Util.postOnUiThread(addSelfToLifecycle);     } else {       lifecycle.addListener(this);     }      ................    }
  5 .RequestManager拿到这个lifecycle,使用Handler切换到主线程进行绑定监听Application生命周期。 private final Runnable addSelfToLifecycle =       new Runnable() {         @Override         public void run() {           lifecycle.addListener(RequestManager.this);         }       };
  6 .通过绑定Application的onStart()方法进行请求处理。public synchronized void onStart() {     //开始请求      resumeRequests();     targetTracker.onStart();   }
  总结如下图所示:
  当Glide在子线程中使用时,只需要监听application的onStart方法进行业务请求的处理,application销毁时,整个应用程序都会被销毁,Glide也会跟随着应用销毁而进行资源释放。所以在子线程中使用,由于传入的context是applicationContext,Glide的生命周期也会和整个应用程序一样。
  以上就是字节面试后总结的几个要点,还不会的同学赶紧学起来吧,感谢您的阅读,创造不易,如果您觉得本篇文章对您有帮助,请点击关注小编,您的支持就是小编创作的最大动力!

雷军披露首台工程车已正式下线,小米股价短线拉升超1。1备受外界关注的小米造车业务近期再次传出新进展。9月30日,据澎湃新闻报道称,小米创始人雷军近日在小米的一次内部讲话中披露,首台小米汽车工程车已正式下线。首台工程车的下线意味着小米造iCloud储存空间不够用怎么办?2步教你双重保险备份数据照片资料相信许多使用苹果手机的小伙伴都使用上了iCloud云备份的功能,它能定时备份咱们苹果手机里的各种APP数据以及重要的相册照片。以至于换手机和丢手机时不至于数据丢失,手机丢了可以再买从4499跌至2699元,LTPO高刷256G五千电池,2K直屏旗舰加速退场手机正面的屏幕形态,有曲面屏和直面屏两种,最初曲面屏仅在旗舰机上才有,但是如今采用曲面屏设计的手机,并不算一定就是高端旗舰,但是如果定价在四千元以上的产品的安卓手机,基本上还是采用荣耀MagicBookV142022评测体验更智能的旗舰商务本去年,荣耀首款旗舰级的商务本第一代荣耀MagicBookV14的发布给人留下了很深的印象,它在拥有比主流轻薄本更优秀的做工设计性能释放和续航表现的基础上,带来了许多更智慧更人性化的消息称一加11R将采用6。7英寸屏幕,搭载骁龙8Gen1芯片IT之家9月30日消息,今年4月29日,一加在海外推出了一加10R手机,该机作为一加ACE的全球版本,售价约3377元。今日,有消息人士带来了一加10R的迭代机型一加11R手机的配又有金主眷顾?FF内部哀嚎之际,贾跃亭再次重掌能否量产?拨乱反正重回正轨,这是FF又一个重大拐点,贾跃亭在社交媒体上如是说。而这并非喧宾夺主,经历了长时间的内斗,北美当地时间9月26日,法拉第未来官方公示董事会已完成重组,现任执行董事长2022中国财富管理行业观察报告迎接时代发展,加速转型升级本文报告来源于德勤编写的2022中国财富管理行业观察报告,完整版共有31页,非常详尽,值得收藏。本报告下载领取方式详见文末本报告目录大纲如下市场发展新时代新机遇新挑战政策监管统一监曾经销量扛把子,全新蔚来ES8能东山再起吗?蔚来ES8作为蔚来的第一款车,为蔚来的发展奠定了基础和立下了汗马功劳。可如今的蔚来ES8销量在蔚来家庭里占比并不高,已开启预售52。863。8万元的2023款蔚来ES8,相对在售23D打印产业链及相关概念股据比利时媒体DeTijd报道,MetaPlatforms已经收购了比利时3D打印镜片公司Luxexcel。3D打印,又称增材制造(AdditiveManufacturing,AM)哪吒S体验纯电版车型,配无边框车门后置单电机!在造车新势力品牌中,哪吒汽车可以说是闷声发大财,看上去不起眼,但家族车型增长率一直保持不错。今天要跟大家来评测的是一台中大型车,名字叫做哪吒S,新车分为增程式版本和纯电版本,厂商指小狐狸钱包的基本设置上篇文章介绍小狐狸钱包如何安装,这篇文章讲安装钱包后,对钱包的一些基本设置,使我们使用起来更安全方便。前言首先我们所讲的小狐狸钱包,它是一款去中心化钱包,去中心化钱包每次在不同设备
构建新时代信访工作新格局,各地信访部门这样部署推进2023年是全面学习贯彻党的二十大精神的开局之年,也是深入贯彻落实信访工作条例和十四五时期信访工作发展规划的关键之年,做好新时代新征程信访工作责任重大使命光荣。1月14日,全国信访西安网评万象耕新,时光不负赶路人2月4日是农历二十四节气的立春,立是开始,春是温暖。立春标志着春回大地,万物复苏,种子发芽。随着春日渐暖,我国农业生产陆续展开。一年之计在于春,一日之计在于晨。春天万物勃发,春天萌永定区司法局永定法律服务所牵手检察院走基层惠民生甘当受灾群众贴心人红网时刻张家界2月8日讯(通讯员李启忠)感谢您们的牵挂鼓励,我们一家有信心从创业失败的困境中走出来,争取早日发家致富回报司法机关的关心。2月8日上午,困难群众李某才紧紧地握住永定法租车市场淡季不淡今年租车市场规模有望超1200亿元租车市场淡季不淡今年租车市场规模有望超1200亿元财联社2月6日电,通常长假过后,租车市场就会回落,今年却一反常态。除了日常短租的订单维持高位,记者在采访中注意到,往年很多以短租为追悔莫及!尤文希望修改博格巴合同!后防中坚获得奖赏对于尤文图斯来说,球队本赛季确实陷入了困境当中。虽然在赛季初期他们完成了多笔非常重要的转会,被外界视作本赛季最有希望拿到联赛冠军的球队之一,然而随着赛季的进行,阿莱格里对于这支球队郑智下课?广州队换帅传闻真相来了,当事人正式发声谭凯元正式宣布留洋西班牙,广州队的青年才俊进一步流失,新赛季就算球队能活下去,以怎么样的阵容出战也是一大疑问,球员不断离开,那么教练员又会跟随吗?日前,在德转网站上就出现奇怪一幕,温江区江安河片区旅游基础设施建设项目凤溪岛简介及方案设想一成都温江区江安河片区旅游基础设施建设项目凤溪岛简介1建设内容对江安河南岸(林泉北街凤凰北大街段)规划绿地进行打造,占地面积约55。5亩,改造现有建筑物,拟打造成结合景观和餐饮以及上任不到五个月!官方贝内文托解雇主帅卡纳瓦罗直播吧2月5日讯官方消息,贝内文托解雇主帅卡纳瓦罗,后者上任不到五个月。与此同时,助理教练小卡纳瓦罗和体育总监福贾也被俱乐部解雇。本周日,贝内文托的训练课将由预备队主帅斯卡拉托(S官方班巴被禁赛4场小里弗斯被禁赛3场北京时间2月5日,NBA今日正式宣布对昨日魔术森林狼冲突的惩罚,魔术中锋默罕默德班巴被禁赛4场,森林狼后卫奥斯汀里弗斯被禁赛3场。除此之外,魔术后卫杰伦萨格斯因锁喉里弗斯并把他拖到夺冠!官方站台,多重身份曝光不简单,身价迎来阶梯式暴涨中国田径最新消息,亚洲飞人苏炳添夺得室内60米冠军迎来了自己新年的赛季喜讯。此次比赛苏炳添与第2名只有0。01秒的差距。更重要的是苏炳添再一次地领先日本选手一步。更是打破网络上的谣福克斯缺阵国王险19分逆转步行者小萨战旧主两双希尔德队史第三人北京时间2月4日,NBA常规赛,步行者主场107104险胜国王,终结4连败。本场比赛国王当家后卫福克斯因个人原因缺阵,同时这也是萨博尼斯与老东家之间的较量,他拿到两双数据。国王最多