Hilt 和协程助力启动框架搭建:解决代码混乱和初始化策略问题

news2024/12/27 3:01:05

关于Hilt的使用,目前已经比较普及了,想必大家已经知道。今天说的是一个如何利用Hilt来做一个启动框架的故事。

是否经历过大型项目的启动优化,一遍过去无任何效果,第二遍过去好几处报错,第三遍过去启动不了,第四遍过去回滚了代码 这都是为什么呢?

不要怀疑,不要询问,不是你技术菜,也不是逻辑有问题(当然没问题,有问题就不叫优化了,叫改bug),而是启动代码写的乱。

在我们软件行业中,或者说每个人的人生中, 这一个字,让多少人悲痛欲绝,让多少人从成功走向了落寞,咳咳,让多少软件行业增本、让多少软件行业无利。

当你打开Application 他的代码量是这样的:

在这里插入图片描述

你是不是很崩溃,我们做启动优化的手法一般是,将能并发的并发,能延后的延后, 总之就是要快。但是面对这种代码,真的不敢动。

正文

这种启动优化的方式理念是非常好的,今天我要做的操作是,解决乱代码,将初始化分开做,在这个过程中,我发现可以利用配置引入协程,或有序、或并发、或依赖、或想怎样就怎样,简直爽到不行

如需完整版性能优化学习文档 请点击领取

利用Hilt 搭建启动框架

  • 首先,使用接口约束初始化框架
// 后续都需要依赖此框架
interface AppInitializer {
    fun init()
}
复制代码
  • 其次,将实现了此接口的初始化器,分开并连起来
class AppInitializers @Inject constructor(
    private val application: Application,
) {

    private val initializers: Set<AppInitializer> by lazy {
        EntryPointAccessors.fromApplication(application, AppInitializerEntryPoint::class.java)
            .getAppInitializers()
    }

    fun init() {
        for (initializer in initializers) {
            initializer.init()
        }
    }
}

提供一个初始化入口,此代码将在APPlication 中调用,我们使用Hilt注解完成Set 的收集,并且在Application中调用init时 启动初始化,注意 这个地方(init)可以将Set 变为Map,指定策略,实现“或有序、或并发、或依赖、或想怎样就怎样,简直爽到不行”

  • 最后,使用

Application 中调用

initializers.init()

Hilt 部分代码

@EntryPoint
@InstallIn(SingletonComponent::class)
interface AppInitializerEntryPoint {
    fun getAppInitializers(): Set<AppInitializer>
}

将所初始化器,分别注册到启动器中

@Module
@InstallIn(SingletonComponent::class)
object AppInitializersModule {
    @Provides
    fun provideAppInitializers(application: Application): Set<AppInitializer> {
        return setOf(
            EmojiInitializer(application),
            UtilsInitializers(application),
        )
    }
}

这个代码比较简单,这就完事了,将乱代码直接分离开了

制定策略

乱代码是分开了,但是其实用性只在编码层面,想要达到“或有序、或并发、或依赖、或想怎样就怎样,简直爽到不行”这种境界,还需要添加策略

修改注册器

fun getStrategyAppInitializers(): Map<AppInitializer.AppInitializerStrategy, List<AppInitializers>>

我们提供一个策略类

enum class AppInitializerStrategy {
    SERIAL,
    PARALLEL,
}

添加到总注册器:

@Provides
fun provideStrategyAppInitializers(application: Application): Map<AppInitializer.AppInitializerStrategy, List<AppInitializer>> {
    return mapOf(
        AppInitializer.AppInitializerStrategy.SERIAL to arrayListOf(EmojiInitializer(application)),
        AppInitializer.AppInitializerStrategy.PARALLEL to arrayListOf(UtilsInitializers(application)),
    )
}

然后在总的启动器中根据不同的策略配合协程一起使用:

strategyInitializers[AppInitializer.AppInitializerStrategy.SERIAL]?.forEach {
    it.init()
}

strategyInitializers[AppInitializer.AppInitializerStrategy.PARALLEL]?.forEach {
    MainScope().launch(Dispatchers.IO) {
        it.init()
    }
}

类图如下:

在这里插入图片描述

以下类和接口:

  1. Application:Android 应用程序类。
  2. AppInitializer 接口:定义了一个 init() 方法,该方法将在应用程序启动时调用,用于执行一些初始化任务。
  3. EmojiInitializer 类:实现了 AppInitializer 接口,用于初始化表情符号相关的内容
  4. UtilsInitializers 类:实现了 AppInitializer 接口,用于初始化一些实用工具。
  5. AppInitializerEntryPoint 接口:定义了获取应用程序初始化器的方法,以及获取不同策略的应用程序初始化器列表的方法。
  6. AppInitializersModule 类:使用 Dagger2 提供 AppInitializerEntryPoint 接口的实例。
  7. AppInitializerStrategy 枚举类:定义了应用程序初始化器的两种不同的策略:串行和并行。

以下关系:

  1. Application 类与 AppInitializerEntryPoint 接口之间的关系:Application 类使用 AppInitializerEntryPoint 接口来获取应用程序初始化器。

  2. AppInitializerEntryPoint 接口与 AppInitializer 接口之间的关系:AppInitializerEntryPoint 接口使用 AppInitializer 接口来表示应用程序初始化器。

  3. AppInitializersModule 类与 AppInitializerEntryPoint 接口之间的关系:AppInitializersModule 类提供了一个 AppInitializerEntryPoint 接口的实例。

  4. AppInitializersModule 类与 AppInitializer 接口之间的关系:AppInitializersModule 类提供了一组 AppInitializer 接口的实例。

  5. EmojiInitializer 类和 UtilsInitializers 类都实现了 AppInitializer 接口,它们之间的关系通过实现关系表示。

完整流程

在这里插入图片描述

  1. User 启动应用程序。
  2. Application 类获取 AppInitializerEntryPoint 接口的实例。
  3. AppInitializerEntryPoint 接口使用 AppInitializersModule 类提供的实例,获取一组应用程序初始化器。
  4. AppInitializerEntryPoint 接口调用每个应用程序初始化器的 init() 方法,按顺序执行初始化任务。
  5. EmojiInitializer 类执行初始化表情符号的任务。
  6. UtilsInitializers 类执行初始化实用工具的任务。

总结

很好的利用Hilt + 协程完成启动框架搭建,完美解决代码乱,和初始化策略问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/467925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开放耳机有什么优缺点,列举出几款口碑不错的开放式耳机

开放式耳机是通过骨头振动传递声音&#xff0c;而不是通过耳道或鼓膜&#xff0c;因此它具有许多优势&#xff0c;比如可以在运动过程中保持对环境的感知&#xff0c;并避免对听力造成伤害。随着科技的进步和用户需求的增加&#xff0c;开放式耳机也在不断更新。目前市面上的开…

springboot+nodejs+vue众筹项目管理系统平台系统

筹资人&#xff08;企业&#xff09;&#xff1a; 1&#xff0c;可以后台注册并登录&#xff0c;发布项目情况&#xff0c;众筹项目需要管理员审核通过后才能展现在前台&#xff0c;没有审核或者审核不通过不会在前台展示&#xff1b; 众筹项目包括项目名称&#xff0c;项目分类…

盲目自学网络安全只会成为脚本小子?

前言&#xff1a;我们来看看怎么学才不会成为脚本小子 一&#xff0c;怎么入门&#xff1f; 1、Web 安全相关概念&#xff08;2 周&#xff09; 了解网络安全相关法律法规 熟悉基本概念&#xff08;SQL 注入、上传、XSS、CSRF、一句话木马等&#xff09;。 通过关键字&…

springboot整合flowable的简单使用

内容来自网络整理&#xff0c;文章最下有引用地址&#xff0c;可跳转至相关资源页面。若有侵权请联系删除 环境&#xff1a; mysql5.7.2 springboot 2.3.9.RELEASE flowable 6.7.2 采坑&#xff1a; 1.当前flowable sql需要与引用的pom依赖一致&#xff0c;否则会报library…

管理后台项目-07-菜单管理和动态展示菜单和按钮

目录 1-菜单管理 1.1-菜单管理列表 1.2-添加|修改功能 1.3-删除菜单 2-动态菜单按钮展示 2.1-路由文件的整理 2.2-动态展示不同的路由 1-菜单管理 当用户点击菜单管理的时候&#xff0c;会展示当前所有菜单&#xff0c;树型结构展示...并且可以对菜单进行新增编辑删除操…

倾斜摄影超大场景的三维模型在网络发布应用遇到常见的问题浅析

倾斜摄影超大场景的三维模型在网络发布应用遇到常见的问题浅析 倾斜摄影超大场景的三维模型在网络发布应用时&#xff0c;常见的问题包括&#xff1a; 1、加载速度慢。由于数据量巨大&#xff0c;网络发布时需要将数据文件分割成多个小文件进行加载&#xff0c;这可能会导致页…

Sonatype Nexus兼容apk格式仓库

Sonatype Nexus兼容apk格式仓库 sonatype/nexus3 当前最新版本&#xff1a;sonatype/nexus3:3.52.0 查看nexus支持的仓库格式 创建一个nexus 容器&#xff1a; docker run -d -p 8081:8081 --name nexus sonatype/nexus3:3.52.0查看启动日志&#xff1a; docker logs nexu…

HTML5画布(图像)

案例1&#xff1a; <!DOCTYPE html> <html> <head lang"en"><meta charset"UTF-8"><title></title><script>window.onloadfunction(){var cdocument.getElementById("myCanvas");var cxt c.getConte…

Vue3 手把手按需引入 Echarts

背景&#xff1a;新项目采用 Vue3 作为前端项目框架&#xff0c;避免不了要使用 echarts&#xff0c;但是在使用的时候&#xff0c;出现了与 Vue2 使用不一样的地方&#xff0c;所以特别记下来&#xff0c;希望给到有需要的同学一些帮助。 下载Echarts依赖 # 自己使用的yarn y…

《Odoo开发者模式必知必会》—— 缘起

Odoo作为业界优秀的开源商务软件&#xff0c;在全球范围内拥有广泛的使用者。在领英国际&#xff0c;可以搜索到全球很多国家都有大量odoo人才需求的招聘信息。在国内&#xff0c;虽然已经有为数不少的企业&#xff0c;他们或者已经使用odoo&#xff0c;或者正在了解odoo&#…

支付宝异步通知说明

如何设置异步通知地址 不同接口接收异步通知设置方式不同&#xff0c;可查看 哪些接口支持触发异步。 设置 notify_url 接收异步 对于支付产生的交易&#xff0c;支付宝会根据原始支付 API 中传入的异步通知地址 notify_url&#xff0c;通过 POST 请求的形式将支付结果作为参…

从零开始学习CTF的完整指南

前言 想要学习CTF却不知从何开始&#xff1f;本文提供了一份完整的指南&#xff0c;从Linux系统基础、网络协议基础、二进制分析、Web安全、杂项题型以及算法与密码学等方面&#xff0c;为零基础小白提供了学习路线和知识点概述。 网络安全 网络安全是 CTF 的基础&#xff0…

还不知道怎么 Mock ,用这 6款工具

以下是几个常用的国外可以mock测试的工具&#xff0c;供参考&#xff1a; MockServer: MockServer 是一个开源的 API mock 测试工具&#xff0c;提供了强大的模拟服务器和 mock 服务功能。MockServer 支持多种语言和格式&#xff0c;包括 Java、.NET、REST、SOAP 等。 WireMoc…

优思学院|做质量管理有七大工具,都是什么?

质量管理七大工具&#xff08;Seven Basic Quality Tools&#xff09;是由日本质量大师石川馨于20世纪50年代首次提出&#xff0c;这些工具被广泛应用于制造业和服务业的质量管理实践中&#xff0c;优思学院认为这七个工具除了是质量人常用的工具之外&#xff0c;也可作为学习六…

OpenGL光照:光照基础

引言 现实世界的光照是极其复杂的&#xff0c;而且会受到诸多因素的影响&#xff0c;这是以目前我们所拥有的处理能力无法模拟的。因此OpenGL的光照仅仅使用了简化的模型并基于对现实的估计来进行模拟&#xff0c;这样处理起来会更容易一些&#xff0c;而且看起来也差不多一样。…

Windows环境下运行StableDiffusion常见问题

目录 常见问题 一、问题1&#xff1a;22.2.2➡23.1.1 Torch is not able to use GPU 解决方案 二、问题2&#xff1a;exit code:128 CLIP did not run sucessfully 解决方案 三、问题3&#xff1a;exit code:128 open-clip did not run sucessfully 解决方案 四、问题4…

工业数字智能化常用系统简介

文章目录 QMS1&#xff0c;IPQC&#xff08;过程检&#xff09;2&#xff0c;OQC&#xff08;出货检&#xff09;3&#xff0c;SPC&#xff08;统计工序控制&#xff09;4&#xff0c;Andon&#xff08;安灯&#xff09;5&#xff0c;其他 MDMMES QMS 质量管理体系&#xff0c;…

【虚拟机】在Windows11上下载安装VMware虚拟机以及Ubuntu(Linux)详细操作

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

获取速卖通aliexpress分类详情 API接口

aliexpress分类详情API接口是速卖通提供的一种产品数据接口&#xff0c;可以帮助速卖通卖家快速地将产品分类、属性、价格等信息&#xff0c;通过 aliexpress API接口来快速生成产品描述、图片、视频等产品信息&#xff0c;让卖家可以更方便地管理自己的产品&#xff0c;快速获…

凌波微课讲师文章|福建农林大学周顺桂团队ISME J:首次发现嗜热病毒参与超高温堆肥过程中碳氮养分转化过程

第一作者&#xff1a;廖汉鹏 通讯作者&#xff1a;周顺桂&#xff0c;Ville-Petri Friman 在线发表时间&#xff1a;2023.04.08 论文网页&#xff1a;https://doi.org/10.1038/s41396-023-01404-1 DOI号&#xff1a;10.1038/s41396-023-01404-1 图片摘要 成果简介 近日&a…