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

做网站工资年新多少在广东成都哪个公司做网站

做网站工资年新多少在广东,成都哪个公司做网站,南美洲网站后缀,官网建设银行文章目录一、前言二、如何阅读源码三、源码解析1、with()Android Glide图片加载框架系列文章 Android Glide图片加载框架#xff08;一#xff09;基本用法 Android Glide图片加载框架#xff08;二#xff09;源码解析之with() Android Glide图片加载框架#xff08;二… 文章目录一、前言二、如何阅读源码三、源码解析1、with()Android Glide图片加载框架系列文章 Android Glide图片加载框架一基本用法 Android Glide图片加载框架二源码解析之with() Android Glide图片加载框架二源码解析之load() Android Glide图片加载框架二源码解析之into() Android Glide图片加载框架三缓存机制 一、前言 在本系列的上一篇文章中我们学习了Glide的基本用法体验了这个图片加载框架的强大功能以及它非常简便的API。还没有看过上一篇文章的朋友建议先去阅读 Android Glide图片加载框架一基本用法。 在多数情况下我们想要在界面上加载并展示一张图片只需要一行代码就能实现如下所示 Glide.with(this).load(url).into(img);虽说只有这简简单单的一行代码但大家可能不知道的是Glide在背后帮我们默默执行了成吨的工作。这个形容词我想了很久因为我觉得用非常多这个形容词不足以描述Glide背后的工作量我查到的英文资料是用tons of work来进行形容的因此我觉得这里使用成吨来形容更加贴切一些。 虽说我们在平时使用Glide的时候格外地简单和方便但是知其然也要知其所以然。那么今天我们就来解析一下Glide的源码看看它在这些简单用法的背后到底执行了多么复杂的工作。 二、如何阅读源码 在开始解析Glide源码之前我想先和大家谈一下该如何阅读源码这个问题也是我平时被问得比较多的因为很多人都觉得阅读源码是一件比较困难的事情。 那么阅读源码到底困难吗 这个当然主要还是要视具体的源码而定。比如同样是图片加载框架我读Volley的源码时就感觉酣畅淋漓并且对Volley的架构设计和代码质量深感佩服。读Glide的源码时却让我相当痛苦代码极其难懂。当然这里我并不是说Glide的代码写得不好只是因为Glide和复杂程度和Volley完全不是在一个量级上的。 那么虽然源码的复杂程度是外在的不可变条件但我们却可以通过一些技巧来提升自己阅读源码的能力。这里我和大家分享一下我平时阅读源码时所使用的技巧简单概括就是八个字抽丝剥茧、点到即止 。 应该认准一个功能点然后去分析这个功能点是如何实现的。但只要去追寻主体的实现逻辑即可千万不要试图去搞懂每一行代码都是什么意思那样很容易会陷入到思维黑洞当中而且越陷越深。因为这些庞大的系统都不是由一个人写出来的每一行代码都想搞明白就会感觉自己是在盲人摸象永远也研究不透。如果只是去分析主体的实现逻辑那么就有比较明确的目的性这样阅读源码会更加轻松也更加有成效。 而今天带大家阅读的Glide源码就非常适合使用这个技巧因为Glide的源码太复杂了千万不要试图去搞明白它每行代码的作用而是应该只分析它的主体实现逻辑。 那么我们本篇文章就先确立好一个目标就是要通过阅读源码搞明白下面这行代码 Glide.with(this).load(url).into(img);到底是如何实现将一张网络图片展示到ImageView上面的。先将Glide的一整套图片加载机制的基本流程梳理清楚然后我们再通过后面的几篇文章具体去了解Glide源码方方面面的细节。 准备好了吗那么我们现在开始。 既然是要阅读Glide的源码那么我们自然需要先将Glide的源码下载下来。其实如果你是使用在 build.gradle 中添加依赖的方式将Glide引入到项目中的那么源码自动就已经下载下来了在Android Studio中就可以直接进行查看。 不过使用添加依赖的方式引入的Glide我们只能看到它的源码但不能做任何的修改如果你还需要修改它的源码的话可以到GitHub上面将它的完整源码下载下来。 Glide的GitHub主页的地址是https://github.com/bumptech/glide 不过在这个地址下载到的永远都是最新的源码有可能还正在处于开发当中。而我们整个系列都是使用Glide 4.8.0这个版本来进行讲解的因此如果你需要专门去下载4.8.0版本的源码可以到这个地址进行下载https://github.com/bumptech/glide/tree/v4.8.0 三、源码解析 1、with() with() 方法是Glide类中的一组静态方法它有好几个方法重载我们来看一下Glide类中所有 with() 方法的方法重载 public class Glide{...NonNullpublic static RequestManager with(NonNull Context context) {return getRetriever(context).get(context);}NonNullpublic static RequestManager with(NonNull Activity activity) {return getRetriever(activity).get(activity);}NonNullpublic static RequestManager with(NonNull FragmentActivity activity) {return getRetriever(activity).get(activity);}NonNullpublic static RequestManager with(NonNull Fragment fragment) {return getRetriever(fragment.getActivity()).get(fragment);}SuppressWarnings(deprecation)DeprecatedNonNullpublic static RequestManager with(NonNull android.app.Fragment fragment) {return getRetriever(fragment.getActivity()).get(fragment);}NonNullpublic static RequestManager with(NonNull View view) {return getRetriever(view.getContext()).get(view);}NonNullprivate static RequestManagerRetriever getRetriever(Nullable Context context) {// Context could be null for other reasons (ie the user passes in null), but in practice it will// only occur due to errors with the Fragment lifecycle.Preconditions.checkNotNull(context,You cannot start a load on a not yet attached View or a Fragment where getActivity() returns null (which usually occurs when getActivity() is called before the Fragment is attached or after the Fragment is destroyed).);return Glide.get(context).getRequestManagerRetriever();}... }可以看到with() 方法的重载种类非常多既可以传入 Activity 也可以传入 Fragment 或者是 Context 。每一个 with() 方法重载的代码都非常简单都是先调用 getRetriever() 方法获取 RequestManagerRetriever 对象然后再调用 RequestManagerRetriever 的实例 get() 方法去获取 RequestManager 对象。 而 RequestManagerRetriever 的实例 get() 方法中的逻辑是什么样的呢我们一起来看一看 public class RequestManagerRetriever implements Handler.Callback {/*** The top application level RequestManager.*/private volatile RequestManager applicationManager;NonNullprivate RequestManager getApplicationManager(NonNull Context context) {// Either an application context or were on a background thread.if (applicationManager null) {synchronized (this) {if (applicationManager null) {// Normally pause/resume is taken care of by the fragment we add to the fragment or// activity. However, in this case since the manager attached to the application will not// receive lifecycle events, we must force the manager to start resumed using// ApplicationLifecycle.// TODO(b/27524013): Factor out this Glide.get() call.Glide glide Glide.get(context.getApplicationContext());applicationManager factory.build(glide,new ApplicationLifecycle(),new EmptyRequestManagerTreeNode(),context.getApplicationContext());}}}return applicationManager;}NonNullpublic 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) {return get(((ContextWrapper) context).getBaseContext());}}return getApplicationManager(context);}NonNullpublic RequestManager get(NonNull FragmentActivity activity) {if (Util.isOnBackgroundThread()) {return get(activity.getApplicationContext());} else {assertNotDestroyed(activity);FragmentManager fm activity.getSupportFragmentManager();return supportFragmentGet(activity, fm, /*parentHint*/ null, isActivityVisible(activity));}}NonNullpublic RequestManager get(NonNull Fragment fragment) {Preconditions.checkNotNull(fragment.getActivity(),You cannot start a load on a fragment before it is attached or after it is destroyed);if (Util.isOnBackgroundThread()) {return get(fragment.getActivity().getApplicationContext());} else {FragmentManager fm fragment.getChildFragmentManager();return supportFragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());}}SuppressWarnings(deprecation)NonNullpublic RequestManager get(NonNull Activity activity) {if (Util.isOnBackgroundThread()) {return get(activity.getApplicationContext());} else {assertNotDestroyed(activity);android.app.FragmentManager fm activity.getFragmentManager();return fragmentGet(activity, fm, /*parentHint*/ null, isActivityVisible(activity));}}SuppressWarnings(deprecation)NonNullpublic RequestManager get(NonNull View view) {if (Util.isOnBackgroundThread()) {return get(view.getContext().getApplicationContext());}Preconditions.checkNotNull(view);Preconditions.checkNotNull(view.getContext(),Unable to obtain a request manager for a view without a Context);Activity activity findActivity(view.getContext());// The view might be somewhere else, like a service.if (activity null) {return get(view.getContext().getApplicationContext());}// Support Fragments.// Although the user might have non-support Fragments attached to FragmentActivity, searching// for non-support Fragments is so expensive pre O and that should be rare enough that we// prefer to just fall back to the Activity directly.if (activity instanceof FragmentActivity) {Fragment fragment findSupportFragment(view, (FragmentActivity) activity);return fragment ! null ? get(fragment) : get(activity);}// Standard Fragments.android.app.Fragment fragment findFragment(view, activity);if (fragment null) {return get(activity);}return get(fragment);}SuppressWarnings(deprecation)DeprecatedNonNullTargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)public RequestManager get(NonNull android.app.Fragment fragment) {if (fragment.getActivity() null) {throw new IllegalArgumentException(You cannot start a load on a fragment before it is attached);}if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT Build.VERSION_CODES.JELLY_BEAN_MR1) {return get(fragment.getActivity().getApplicationContext());} else {android.app.FragmentManager fm fragment.getChildFragmentManager();return fragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());}}SuppressWarnings(deprecation)DeprecatedNonNullRequestManagerFragment getRequestManagerFragment(Activity activity) {return getRequestManagerFragment(activity.getFragmentManager(), /*parentHint*/ null, isActivityVisible(activity));}SuppressWarnings(deprecation)NonNullprivate RequestManagerFragment getRequestManagerFragment(NonNull final android.app.FragmentManager fm,Nullable android.app.Fragment parentHint,boolean isParentVisible) {RequestManagerFragment current (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);if (current null) {current pendingRequestManagerFragments.get(fm);if (current null) {current new RequestManagerFragment();current.setParentFragmentHint(parentHint);if (isParentVisible) {current.getGlideLifecycle().onStart();}pendingRequestManagerFragments.put(fm, current);fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();}}return current;}SuppressWarnings({deprecation, DeprecatedIsStillUsed})DeprecatedNonNullprivate RequestManager fragmentGet(NonNull Context context,NonNull android.app.FragmentManager fm,Nullable android.app.Fragment parentHint,boolean isParentVisible) {RequestManagerFragment current getRequestManagerFragment(fm, parentHint, isParentVisible);RequestManager requestManager current.getRequestManager();if (requestManager null) {// TODO(b/27524013): Factor out this Glide.get() call.Glide glide Glide.get(context);requestManager factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);current.setRequestManager(requestManager);}return requestManager;}NonNullprivate SupportRequestManagerFragment getSupportRequestManagerFragment(NonNull final FragmentManager fm, Nullable Fragment parentHint, boolean isParentVisible) {SupportRequestManagerFragment current (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);if (current null) {current pendingSupportRequestManagerFragments.get(fm);if (current null) {current new SupportRequestManagerFragment();current.setParentFragmentHint(parentHint);if (isParentVisible) {current.getGlideLifecycle().onStart();}pendingSupportRequestManagerFragments.put(fm, current);fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();}}return current;}NonNullprivate RequestManager supportFragmentGet(NonNull Context context,NonNull FragmentManager fm,Nullable Fragment parentHint,boolean isParentVisible) {SupportRequestManagerFragment current getSupportRequestManagerFragment(fm, parentHint, isParentVisible);RequestManager requestManager current.getRequestManager();if (requestManager null) {// TODO(b/27524013): Factor out this Glide.get() call.Glide glide Glide.get(context);requestManager factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);current.setRequestManager(requestManager);}return requestManager;} }上述代码虽然看上去逻辑有点复杂但是将它们梳理清楚后还是很简单的。 RequestManagerRetriever 类中看似有很多个 get() 方法的重载什么Context参数Activity参数Fragment参数等等实际上只有两种情况而已即传入Application类型的参数和传入非Application类型的参数 。 Application类型参数 如果在 Glide.with() 方法中传入的是一个 Application对象 那么这里就会调用带有Context参数的get()方法重载然后会在第48行调用 getApplicationManager() 方法来获取一个 RequestManager 对象。其实这是最简单的一种情况因为Application对象的生命周期即应用程序的生命周期因此Glide并不需要做什么特殊的处理它自动就是和应用程序的生命周期是同步的如果应用程序关闭的话Glide的加载也会同时终止。 非Application类型参数 不管你在 Glide.with() 方法中传入的是Activity、FragmentActivity、v4包下的Fragment、还是app包下的Fragment最终的流程都是一样的那就是 会向当前的Activity当中添加一个隐藏的Fragment 。具体添加的逻辑是在上述代码的第176行和第215行分别对应的app包和v4包下的两种Fragment的情况。 这里为什么要添加一个隐藏的Fragment呢 因为Glide需要知道加载的生命周期。很简单的一个道理如果你在某个Activity上正在加载着一张图片结果图片还没加载出来Activity就被用户关掉了那么图片还应该继续加载吗当然不应该。可是 Glide并没有办法知道Activity的生命周期于是Glide就使用了添加隐藏Fragment的这种小技巧因为Fragment的生命周期和Activity是同步的如果Activity被销毁了Fragment是可以监听到的这样Glide就可以捕获这个事件并停止图片加载了。 这里额外再提一句从第54行代码可以看出如果我们是在非主线程当中使用的Glide那么不管你是传入的Activity还是Fragment都会被强制当成Application来处理 。不过其实这就属于是在分析代码的细节了本篇文章我们将会把目光主要放在Glide的主线工作流程上面后面不会过多去分析这些细节方面的内容。 总体来说第一个with()方法的源码还是比较好理解的。其实就是为了得到一个RequestManager对象而已然后 Glide会根据我们传入with()方法的参数来确定图片加载的生命周期 并没有什么特别复杂的逻辑。不过复杂的逻辑还在后面等着我们呢接下来我们开始分析第二步load()方法。
http://wiki.neutronadmin.com/news/275810/

相关文章:

  • 高端集团网站建设apk开发
  • 腾讯网站统计代码网站建设的要求有哪些方面
  • 网站开发需要学php吗郑州建材网站建设
  • 兰溪企业网站搭建地址东莞短视频推广多少钱
  • 湖南沙坪建设集团有限公司网站大学学部网站建设工作
  • 政务咨询投诉举报网站建设无锡的网站建设公司
  • 响应式网站框架不用下载qq在线qq登录聊天
  • 网站开发语言总结有哪些中国传统美食网页制作素材
  • 怎么做网站的排名网站开发架构文档
  • 网站开发 安全验证南通做网站公司
  • 深圳做网站推广的公司网站建设的可行性分析报告
  • 东莞网站制作有名 乐云践新crm系统的销售管理功能包括
  • 昆明网站优化排名推广新手做网站需要什么
  • 南宁网站运营哪家好宝安在深圳算什么档次
  • 百度收录最快的网站手机怎么上wap网站
  • 广州 seo的网站电商seo推广
  • 网站网络营销阿里云自助建站教程
  • 营销型网站系统学ps有用还是网页制作
  • 网站建设 目的图片下载 wordpress
  • 福州网站免费制作微信接口文档
  • 网站下载系统如何做系统怎么进入网站后台图片
  • 缩短链接网站阿里巴巴专门做外贸的网站
  • 凡科网做的网站做网站要不要35类商标
  • 公司网站建设费用包括哪些加盟产品网站建设方案
  • 有专门做美发的网站吗网站文字不能编辑器
  • 成都建网站公司电话如何搭建 seo网站
  • 营销型网站建设思路网站编程设计方向
  • 网站开发技术部经理素质模型策划公司排名
  • 石龙镇网站建设怎么做装修网站平台
  • 建设中心小学网站制作好网站怎么导入