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

佛山企业网站设计惠州企业网站seo

佛山企业网站设计,惠州企业网站seo,江苏网站建设简介模板,抽奖网站怎么制作一、引言 在现代的 Android 应用开发中#xff0c;图片加载是一个常见且重要的功能。Glide 作为一款广泛使用的图片加载框架#xff0c;以其高效、灵活和易用的特点受到了开发者的青睐。其中#xff0c;线程管理模块是 Glide 框架中至关重要的一部分#xff0c;它负责协调…一、引言 在现代的 Android 应用开发中图片加载是一个常见且重要的功能。Glide 作为一款广泛使用的图片加载框架以其高效、灵活和易用的特点受到了开发者的青睐。其中线程管理模块是 Glide 框架中至关重要的一部分它负责协调不同线程之间的工作确保图片的加载、解码、处理等操作能够高效、有序地进行。合理的线程管理可以提高应用的性能避免主线程阻塞从而为用户提供流畅的交互体验。 本文将深入 Glide 框架的源码详细剖析其线程管理模块的原理。从线程池的创建和配置到不同任务在各个线程之间的调度和执行每一个步骤都会结合具体的代码进行分析。同时还会探讨线程管理模块与 Glide 其他模块之间的协作关系以及如何在实际开发中合理利用线程管理来优化图片加载性能。 二、线程管理模块概述 Glide 的线程管理模块主要负责以下几个方面的工作 线程池的创建和管理Glide 使用多个线程池来处理不同类型的任务如网络请求、磁盘缓存读写、图片解码等。通过合理配置线程池的参数可以提高任务的执行效率。任务的调度和执行根据任务的类型和优先级将任务分配到合适的线程池中执行。同时处理任务的排队和并发控制确保系统资源的合理利用。线程间的通信和同步在不同线程之间传递数据和状态信息保证各个模块之间的协作和数据的一致性。例如在图片加载完成后将结果从子线程传递到主线程进行显示。 三、线程池的创建和配置 3.1 线程池的种类 Glide 中主要使用了以下几种线程池 DiskCacheService用于处理磁盘缓存的读写操作。磁盘 I/O 操作通常比较耗时使用单独的线程池可以避免阻塞其他任务。SourceService用于处理网络请求和图片解码等操作。这些操作可能会消耗大量的 CPU 和网络资源使用专门的线程池可以提高处理效率。AnimationExecutor用于处理动画相关的任务。动画需要在主线程或特定的线程中执行以保证动画的流畅性。 3.2 线程池的创建和配置源码分析 3.2.1 DiskCacheService 线程池 DiskCacheService 是一个单线程的线程池用于处理磁盘缓存的读写操作。以下是其创建和配置的源码 java // GlideExecutor 类中创建 DiskCacheService 线程池的方法 private static GlideExecutor newDiskCacheExecutor() {// 线程池的核心线程数为 1即单线程int corePoolSize 1;// 线程池的最大线程数也为 1int maximumPoolSize 1;// 线程空闲时的存活时间为 0 毫秒long keepAliveTime 0L;// 时间单位为毫秒TimeUnit unit TimeUnit.MILLISECONDS;// 使用 LinkedBlockingQueue 作为任务队列BlockingQueueRunnable workQueue new LinkedBlockingQueue();// 创建一个线程工厂用于创建线程ThreadFactory threadFactory new DefaultThreadFactory(disk-cache, Process.THREAD_PRIORITY_BACKGROUND);// 创建一个线程池执行器ThreadPoolExecutor executor new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory);// 将线程池执行器包装成 GlideExecutor 对象并返回return new GlideExecutor(executor, /*isShutdownAllowed*/ true); }在上述代码中newDiskCacheExecutor 方法创建了一个单线程的线程池。核心线程数和最大线程数都设置为 1确保只有一个线程在处理磁盘缓存的读写操作。使用 LinkedBlockingQueue 作为任务队列保证任务按顺序执行。线程空闲时的存活时间为 0 毫秒即线程在空闲时会立即终止。最后将线程池执行器包装成 GlideExecutor 对象返回。 3.2.2 SourceService 线程池 SourceService 是一个多线程的线程池用于处理网络请求和图片解码等操作。以下是其创建和配置的源码 java // GlideExecutor 类中创建 SourceService 线程池的方法 private static GlideExecutor newSourceExecutor() {// 获取可用的处理器核心数int availableProcessors Runtime.getRuntime().availableProcessors();// 线程池的核心线程数为可用处理器核心数的一半int corePoolSize Math.max(1, availableProcessors / 2);// 线程池的最大线程数为可用处理器核心数int maximumPoolSize availableProcessors;// 线程空闲时的存活时间为 60 秒long keepAliveTime 60L;// 时间单位为秒TimeUnit unit TimeUnit.SECONDS;// 使用 SynchronousQueue 作为任务队列BlockingQueueRunnable workQueue new SynchronousQueue();// 创建一个线程工厂用于创建线程ThreadFactory threadFactory new DefaultThreadFactory(source, Process.THREAD_PRIORITY_BACKGROUND);// 创建一个线程池执行器ThreadPoolExecutor executor new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory);// 将线程池执行器包装成 GlideExecutor 对象并返回return new GlideExecutor(executor, /*isShutdownAllowed*/ true); }在上述代码中newSourceExecutor 方法创建了一个多线程的线程池。核心线程数为可用处理器核心数的一半最大线程数为可用处理器核心数这样可以充分利用系统资源。使用 SynchronousQueue 作为任务队列该队列不存储任务而是直接将任务交给线程处理提高了任务的执行效率。线程空闲时的存活时间为 60 秒当线程空闲超过 60 秒时会被终止。最后将线程池执行器包装成 GlideExecutor 对象返回。 3.2.3 AnimationExecutor 线程池 AnimationExecutor 用于处理动画相关的任务。以下是其创建和配置的源码 java // GlideExecutor 类中创建 AnimationExecutor 线程池的方法 private static GlideExecutor newAnimationExecutor() {// 线程池的核心线程数为 1int corePoolSize 1;// 线程池的最大线程数为 1int maximumPoolSize 1;// 线程空闲时的存活时间为 0 毫秒long keepAliveTime 0L;// 时间单位为毫秒TimeUnit unit TimeUnit.MILLISECONDS;// 使用 LinkedBlockingQueue 作为任务队列BlockingQueueRunnable workQueue new LinkedBlockingQueue();// 创建一个线程工厂用于创建线程ThreadFactory threadFactory new DefaultThreadFactory(animation, Process.THREAD_PRIORITY_DISPLAY);// 创建一个线程池执行器ThreadPoolExecutor executor new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory);// 将线程池执行器包装成 GlideExecutor 对象并返回return new GlideExecutor(executor, /*isShutdownAllowed*/ true); }在上述代码中newAnimationExecutor 方法创建了一个单线程的线程池。核心线程数和最大线程数都设置为 1确保动画任务按顺序执行。使用 LinkedBlockingQueue 作为任务队列保证任务的顺序性。线程空闲时的存活时间为 0 毫秒即线程在空闲时会立即终止。最后将线程池执行器包装成 GlideExecutor 对象返回。 3.3 线程池的获取和使用 在 Glide 中可以通过 GlideExecutor 类的静态方法获取不同的线程池。以下是获取 DiskCacheService 线程池的示例代码 java // 获取 DiskCacheService 线程池 GlideExecutor diskCacheExecutor GlideExecutor.newDiskCacheExecutor(); // 提交一个任务到 DiskCacheService 线程池 diskCacheExecutor.execute(new Runnable() {Overridepublic void run() {// 执行磁盘缓存的读写操作// ...} });通过调用 GlideExecutor 类的 newDiskCacheExecutor 方法可以获取 DiskCacheService 线程池然后使用 execute 方法提交一个任务到该线程池。其他线程池的获取和使用方式类似。 四、任务的调度和执行 4.1 任务的分类 在 Glide 中任务主要分为以下几类 磁盘缓存读写任务如从磁盘缓存中读取图片数据或将图片数据写入磁盘缓存。网络请求任务从网络获取图片数据。图片解码任务将图片数据解码为 Bitmap 或其他可显示的格式。动画任务处理图片的动画效果。 4.2 任务调度的源码分析 Glide 通过 EngineJob 类来管理任务的调度和执行。以下是 EngineJob 类中任务调度的部分源码 java // EngineJob 类负责管理任务的调度和执行 public class EngineJobR implements DecodeJob.CallbackR {private final GlideExecutor diskCacheExecutor; // 磁盘缓存线程池private final GlideExecutor sourceExecutor; // 源数据线程池private final GlideExecutor animationExecutor; // 动画线程池private DecodeJobR decodeJob; // 解码任务public EngineJob(GlideExecutor diskCacheExecutor,GlideExecutor sourceExecutor,GlideExecutor animationExecutor) {this.diskCacheExecutor diskCacheExecutor;this.sourceExecutor sourceExecutor;this.animationExecutor animationExecutor;}// 开始执行任务public void start(DecodeJobR decodeJob) {this.decodeJob decodeJob;// 将解码任务提交到磁盘缓存线程池执行diskCacheExecutor.execute(decodeJob);}Overridepublic void onResourceDecoded(ResourceR resource, DataSource dataSource) {// 当资源解码完成后根据数据源类型选择合适的线程池执行后续任务if (dataSource DataSource.DATA_DISK_CACHE) {// 如果数据来自磁盘缓存将任务提交到源数据线程池执行sourceExecutor.execute(new ResourceReadyCallback(resource, dataSource));} else {// 否则直接在当前线程执行后续任务handleResultOnMainThread(resource, dataSource);}}// 在主线程处理结果private void handleResultOnMainThread(ResourceR resource, DataSource dataSource) {// ...}// 资源准备好的回调任务private class ResourceReadyCallback implements Runnable {private final ResourceR resource;private final DataSource dataSource;public ResourceReadyCallback(ResourceR resource, DataSource dataSource) {this.resource resource;this.dataSource dataSource;}Overridepublic void run() {// 处理资源准备好的逻辑handleResultOnMainThread(resource, dataSource);}} }在上述代码中EngineJob 类包含了三个线程池diskCacheExecutor、sourceExecutor 和 animationExecutor。在 start 方法中将解码任务 decodeJob 提交到 diskCacheExecutor 线程池执行。当资源解码完成后在 onResourceDecoded 方法中根据数据源类型选择合适的线程池执行后续任务。如果数据来自磁盘缓存将任务提交到 sourceExecutor 线程池执行否则直接在当前线程执行后续任务。 4.3 任务执行的源码分析 任务的执行主要通过 Runnable 接口实现。以 DecodeJob 类为例以下是其实现 Runnable 接口的部分源码 java // DecodeJob 类实现了 Runnable 接口用于执行解码任务 public class DecodeJobR implements Runnable {private final EngineJobR engineJob; // 引擎任务private final DataFetcherGenerator generator; // 数据获取生成器public DecodeJob(EngineJobR engineJob, DataFetcherGenerator generator) {this.engineJob engineJob;this.generator generator;}Overridepublic void run() {try {// 执行解码任务boolean isResourceDecoded decodeFromSource();if (isResourceDecoded) {// 如果资源解码成功通知引擎任务engineJob.onResourceDecoded(resource, dataSource);} else {// 如果资源解码失败通知引擎任务engineJob.onLoadFailed(new GlideException(Failed to decode resource));}} catch (Exception e) {// 处理异常情况通知引擎任务engineJob.onLoadFailed(e);}}// 从源数据解码资源private boolean decodeFromSource() throws Exception {// ...return false;} }在上述代码中DecodeJob 类实现了 Runnable 接口的 run 方法。在 run 方法中调用 decodeFromSource 方法执行解码任务。如果资源解码成功调用 engineJob 的 onResourceDecoded 方法通知引擎任务如果解码失败调用 engineJob 的 onLoadFailed 方法通知引擎任务。 五、线程间的通信和同步 5.1 线程间通信的方式 在 Glide 中线程间的通信主要通过以下几种方式实现 Handler 机制用于在子线程和主线程之间传递消息。例如在图片加载完成后将结果从子线程传递到主线程进行显示。回调接口通过定义回调接口在不同线程之间传递数据和状态信息。例如在 DecodeJob 完成解码任务后通过回调接口通知 EngineJob。 5.2 Handler 机制的源码分析 Glide 使用 Handler 机制在子线程和主线程之间传递消息。以下是相关的源码分析 java // MainThreadExecutor 类用于在主线程执行任务 public class MainThreadExecutor implements Executor {private static final Handler MAIN_THREAD_HANDLER new Handler(Looper.getMainLooper());Overridepublic void execute(Runnable command) {// 将任务提交到主线程的消息队列中执行MAIN_THREAD_HANDLER.post(command);} }在上述代码中MainThreadExecutor 类实现了 Executor 接口用于在主线程执行任务。通过 Handler 的 post 方法将任务提交到主线程的消息队列中执行。以下是在 EngineJob 类中使用 MainThreadExecutor 的示例代码 java // EngineJob 类中在主线程处理结果的方法 private void handleResultOnMainThread(ResourceR resource, DataSource dataSource) {// 获取主线程执行器MainThreadExecutor mainThreadExecutor new MainThreadExecutor();// 将任务提交到主线程执行mainThreadExecutor.execute(new Runnable() {Overridepublic void run() {// 在主线程处理资源结果// ...}}); }在 handleResultOnMainThread 方法中创建了一个 MainThreadExecutor 对象然后使用 execute 方法将任务提交到主线程执行。 5.3 回调接口的源码分析 回调接口是 Glide 中常用的线程间通信方式。以 DecodeJob 和 EngineJob 之间的通信为例以下是相关的源码分析 java // DecodeJob 类的回调接口 public interface CallbackR {// 资源解码完成的回调方法void onResourceDecoded(ResourceR resource, DataSource dataSource);// 加载失败的回调方法void onLoadFailed(GlideException e); }// DecodeJob 类 public class DecodeJobR implements Runnable {private final EngineJobR engineJob;public DecodeJob(EngineJobR engineJob) {this.engineJob engineJob;}Overridepublic void run() {try {// 执行解码任务boolean isResourceDecoded decodeFromSource();if (isResourceDecoded) {// 如果资源解码成功通知引擎任务engineJob.onResourceDecoded(resource, dataSource);} else {// 如果资源解码失败通知引擎任务engineJob.onLoadFailed(new GlideException(Failed to decode resource));}} catch (Exception e) {// 处理异常情况通知引擎任务engineJob.onLoadFailed(e);}} }// EngineJob 类实现了 DecodeJob 的回调接口 public class EngineJobR implements DecodeJob.CallbackR {Overridepublic void onResourceDecoded(ResourceR resource, DataSource dataSource) {// 处理资源解码完成的逻辑// ...}Overridepublic void onLoadFailed(GlideException e) {// 处理加载失败的逻辑// ...} }在上述代码中DecodeJob 类定义了一个回调接口 Callback包含了 onResourceDecoded 和 onLoadFailed 两个方法。EngineJob 类实现了该回调接口当 DecodeJob 完成解码任务后会调用 EngineJob 的相应回调方法从而实现了线程间的通信。 六、线程管理模块与其他模块的协作 6.1 与缓存模块的协作 线程管理模块与缓存模块密切协作确保磁盘缓存的读写操作在合适的线程中执行。例如在 DecodeJob 中如果需要从磁盘缓存中读取图片数据会将该任务提交到 DiskCacheService 线程池执行。以下是相关的源码分析 java // DecodeJob 类中从磁盘缓存读取数据的方法 private boolean decodeFromCache() {// 创建一个磁盘缓存读取任务DiskCacheGenerator generator new DiskCacheGenerator(this,diskCache,diskCacheService);// 将任务提交到磁盘缓存线程池执行diskCacheService.execute(generator);return false; }在上述代码中decodeFromCache 方法创建了一个 DiskCacheGenerator 对象该对象负责从磁盘缓存中读取数据。然后将该任务提交到 diskCacheService 线程池执行。 6.2 与网络模块的协作 线程管理模块与网络模块协作确保网络请求任务在合适的线程中执行。例如在 SourceGenerator 中如果需要从网络获取图片数据会将该任务提交到 SourceService 线程池执行。以下是相关的源码分析 java // SourceGenerator 类中从网络获取数据的方法 private boolean startNext() {// 创建一个网络数据获取器HttpUrlFetcher fetcher new HttpUrlFetcher(url, timeout);// 将任务提交到源数据线程池执行sourceExecutor.execute(new Runnable() {Overridepublic void run() {try {// 执行网络请求InputStream inputStream fetcher.loadData(priority, this);// 处理网络请求结果// ...} catch (IOException e) {// 处理网络请求异常// ...}}});return true; }在上述代码中startNext 方法创建了一个 HttpUrlFetcher 对象该对象负责从网络获取图片数据。然后将该任务提交到 sourceExecutor 线程池执行。 6.3 与动画模块的协作 线程管理模块与动画模块协作确保动画任务在合适的线程中执行。例如在 AnimatableDrawable 中如果需要执行动画效果会将该任务提交到 AnimationExecutor 线程池执行。以下是相关的源码分析 java // AnimatableDrawable 类中执行动画的方法 public void start() {// 创建一个动画任务AnimationRunnable animationRunnable new AnimationRunnable(this);// 将任务提交到动画线程池执行animationExecutor.execute(animationRunnable); }// 动画任务类 private class AnimationRunnable implements Runnable {private final AnimatableDrawable drawable;public AnimationRunnable(AnimatableDrawable drawable) {this.drawable drawable;}Overridepublic void run() {// 执行动画逻辑// ...} }在上述代码中start 方法创建了一个 AnimationRunnable 对象该对象负责执行动画逻辑。然后将该任务提交到 animationExecutor 线程池执行。 七、线程管理模块的性能优化 7.1 合理配置线程池参数 合理配置线程池的参数可以提高任务的执行效率。例如根据系统的处理器核心数和任务的类型调整线程池的核心线程数和最大线程数。在 SourceService 线程池中核心线程数设置为可用处理器核心数的一半最大线程数设置为可用处理器核心数这样可以充分利用系统资源。 7.2 任务的优先级管理 Glide 可以通过设置任务的优先级来管理任务的执行顺序。例如在 Priority 枚举中定义了不同的优先级 java // Priority 枚举定义了任务的优先级 public enum Priority {IMMEDIATE, // 立即执行HIGH, // 高优先级NORMAL, // 正常优先级LOW // 低优先级 }在提交任务时可以指定任务的优先级线程池会根据优先级来调度任务。例如 java // 提交一个高优先级的任务到源数据线程池 sourceExecutor.execute(new Runnable() {Overridepublic void run() {// 执行高优先级任务// ...} }, Priority.HIGH);7.3 避免线程阻塞 在任务执行过程中要避免线程阻塞以免影响其他任务的执行。例如在进行网络请求时要使用异步方式进行避免在主线程中执行耗时的网络操作。Glide 在处理网络请求时会将网络请求任务提交到 SourceService 线程池执行避免阻塞主线程。 7.4 线程池的复用和关闭 在使用线程池时要注意线程池的复用和关闭。避免频繁创建和销毁线程池以减少系统资源的消耗。同时在应用退出时要及时关闭线程池释放资源。例如在 Glide 类的 shutdown 方法中会关闭所有的线程池 java // Glide 类的 shutdown 方法 public void shutdown() {// 关闭磁盘缓存线程池diskCacheExecutor.shutdown();// 关闭源数据线程池sourceExecutor.shutdown();// 关闭动画线程池animationExecutor.shutdown(); }八、线程管理模块的异常处理 8.1 任务执行异常的处理 在任务执行过程中可能会出现各种异常情况如网络异常、解码异常等。Glide 在任务执行过程中会捕获这些异常并进行相应的处理。例如在 DecodeJob 类的 run 方法中会捕获异常并通知 EngineJob java // DecodeJob 类的 run 方法 Override public void run() {try {// 执行解码任务boolean isResourceDecoded decodeFromSource();if (isResourceDecoded) {// 如果资源解码成功通知引擎任务engineJob.onResourceDecoded(resource, dataSource);} else {// 如果资源解码失败通知引擎任务engineJob.onLoadFailed(new GlideException(Failed to decode resource));}} catch (Exception e) {// 处理异常情况通知引擎任务engineJob.onLoadFailed(e);} }在上述代码中run 方法捕获了所有异常并调用 engineJob 的 onLoadFailed 方法通知引擎任务。 8.2 线程池异常的处理 线程池在执行任务时也可能会出现异常如线程池已满、线程创建失败等。Glide 通过设置线程池的拒绝策略来处理这些异常。例如在 ThreadPoolExecutor 中可以设置拒绝策略 java // 创建一个线程池执行器并设置拒绝策略 ThreadPoolExecutor executor new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory,new ThreadPoolExecutor.CallerRunsPolicy() // 使用 CallerRunsPolicy 拒绝策略 );在上述代码中使用 CallerRunsPolicy 拒绝策略当线程池已满时会将任务返回给调用者线程执行。 九、总结 Glide 的线程管理模块是其高效运行的关键之一。通过合理创建和配置线程池将不同类型的任务分配到合适的线程池中执行实现了任务的高效调度和执行。同时利用线程间的通信和同步机制确保了各个模块之间的协作和数据的一致性。 线程管理模块与 Glide 的其他模块密切协作如缓存模块、网络模块和动画模块共同完成图片的加载、解码和显示等任务。在实际开发中要合理利用线程管理模块的功能进行性能优化
http://www.hkea.cn/news/14570064/

相关文章:

  • wordpress双站 中英文在中国建设工程造价管理协会网站
  • 官方制作网站长沙网站seo报价
  • 网站首页被k 做跳转怎么做系部网站首页
  • 高清免费观看电视网站如何把自己做的网站
  • 做公众号必了解的网站域名收录提交入口
  • 蓝色 宽屏 网站 模板下载餐饮网站方案
  • 做打鱼网站需要多少钱企业邮箱如何申请
  • 做类似简书的网站俄罗斯ip地址
  • 网站布局的好坏的几个要素雨花区最新情况
  • 自助建站基础工作主要包括()深圳网站建设推选上榜网络
  • 手机端网站加盟网站开发重点难点
  • 金融行业网站开发易企秀h5制作官网
  • php做的网站安全吗怎么投诉网站制作公司
  • 网站怎么做才被收录快正邦设计招聘
  • 医院网站开发违法吗做PS的赚钱的网站
  • 做的好的微信商城网站能上外国网站dns
  • 网站模板怎么改移动网站有哪些
  • 网站建设设计平台做外贸怎么登陆国外网站
  • 淄博 网站建设个人网站设计图片
  • 坂田做网站的公司给自己广告公司宣传
  • 用群晖nas做网站创业项目排行榜前十名
  • 网站建设企业排行榜wordpress快速部署
  • 手机网站用模版苏州互联网公司集中在哪里
  • 东莞网站开发前三强网站建设需要什么条件
  • 个人购物网站怎么备案吴江建设工程招标中心网站
  • 中兴建设有限公司网站外贸网站源代码下载
  • 常州在线制作网站环保类网站模板免费下载
  • 手机网站你了解的大连网站建设策划
  • 做网站投放广告vs2008做网站
  • 本科学院网站建设方案网站建设技术实现难点