Jetpack Startup 优雅完成库的初始化和方法接口简化

目录

  • 1.Startup组件是什么
  • 2.Startup组件能做啥
    • 2.1 startup组件可以简化用户使用我们提供的库的流程。
    • 2.2 简化库提供给使用者的API接口
  • 3.如何使用Startup组件
    • 3.1 引入依赖
    • 3.2 创建一个初始化的类继承Initializer
    • 3.3 在我们库的AndroidManifest.xml中加入配置
  • 4.使用Startup组件的注意点

1.Startup组件是什么

Startup组件是Google Jetpack推出的,它提供了一种直接高效的方式用来在应用程序启动的时候对多个组件进行初始化,开发者可以依靠它来显示地设置多个组件间的初始化顺序,并优化应用的启动时间。在没有Startup组件之前,很多的三方库为了简化开发者的使用成本,常常会定义一个ContentProvider获取Context的对象,然后自动完成库的初始化,也就是我们之前使用库的时候,总是需要在Application中调用下某某库的:XXXLib.init(Context)方法,主要是将我们的Context传递给三方库。由于ContentProvider会在Application的onCreate()之前调用,所以可以通过定义ContentProvider的方式提前获取到Context。但是这样做会有问题的,因为如果每个三方库都定义一个自己的ContentProvider,并且在拿Context的时候都做了耗时操作,这样就会导致应用的启动变慢和长时间黑屏的问题。因此,Google就推出了Startup组件,Startup组件允许库的开发者和App的开发者共享一个ContentProvider,用于完成各自的初始化逻辑,并且支持设置组件之间的初始化顺序。这样应用就可以选择先初始化需要马上使用到的库,其他的不需要马上使用的库后面再初始化。从而达到缩短应用的启动时间。

2.Startup组件能做啥

2.1 startup组件可以简化用户使用我们提供的库的流程。

比如我们非常熟悉的内存泄漏检测工具LeakCarry,在没有使用Startup组件之前,使用它需要在Application中初始化一下,如下所示:

在这里插入图片描述也就是说用户不仅需要引入依赖,还需要做初始化工作。但是引入了startup组件后,使用LeakCanary就可以只引入依赖了。LeakCanary库会通过startup组件提供的API拿到想要的Context,然后进行内存泄漏的检测工作。下面是LeakCanary库使用startup组件的截图:
首先是Manifest中

在这里插入图片描述初始化类:
在这里插入图片描述然后我们就可以看到在LeakCanary库中就能拿到了Context并进行初始化了。所以我们使用的时候,只需要引入依赖:

dependencies {
  // debugImplementation because LeakCanary should only run in debug builds.
  debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
}

就可以使用LeakCanary库检测内存泄漏了。

2.2 简化库提供给使用者的API接口

现在的VR眼镜基本上都是基于Android系统的,而3D场景的渲染都依赖于Unity和OpenGL,Unity和OpenGL渲染时的数据有一部分是需要Android系统提供的,所以就需要Android开发接口提供给Unity或者是OpenGL调用。但是很多的时候接口都需要使用单例的方式提供并且需要传递Context,如下所示:

在这里插入图片描述这样调用者在调用的时候就需要使用LoadAllAPIEngine.getInstance(context).getInfo()的方式去使用我们提供的服务,而且还需要调用下LoadAllAPIEngine.getInstance(context).init()方法让我们提供接口的库做一些初始化的动作。在开发的过程中发现使用接口的同事会经常多次调用init()方法,或者是忘记调用release()方法,导致出现一些未知的问题。而且如果是OpenGL调用我们的接口时,往往需要反射获取Android的Context,然后再每次调用接口时传递给提供服务的sdk库。这些都增加了SDK使用者的负担,同时也让我们查问题时显得很吃力。

而利用Startup组件可以可以解决这个问题,使用了startup组件后,使用者只要引入我们的库依赖,就可以使用我们的提供的接口方法获取到想要的信息了,使用startup组件后,调用接口就可以变成。 LoadAllAPIEngine.getInstance().getInfo()了,并且不用调用LoadAllAPIEngine.getInstance(context).init()方法,直接使用接口即可。

3.如何使用Startup组件

3.1 引入依赖

implementation("androidx.startup:startup-runtime:1.1.1")

3.2 创建一个初始化的类继承Initializer

然后重写create()方法和dependencies()方法。然后在create()方法中就可以拿到引用我们库的APP的Context了。

class StartupInitializer : Initializer<StartupInitializer>{
    override fun create(context: Context): StartupInitializer = apply {
        val application = context.applicationContext as Application
        application.registerActivityLifecycleCallbacks(object 
        :ActivityLifecycleCallbacks{
            override fun onActivityCreated(activity: Activity, 
            savedInstanceState: Bundle?) {
                FMSdk.getInstance().init(activity)
                Log.d(TAG,"onActivityCreated")
            }

            override fun onActivityStarted(activity: Activity) {

            }

            override fun onActivityResumed(activity: Activity) {
                FMSdk.getInstance().resume()
                Log.d(TAG,"onActivityResumed")

            }

            override fun onActivityPaused(activity: Activity) {

            }

            override fun onActivityStopped(activity: Activity) {
                FMSdk.getInstance().pause()
                Log.d(TAG,"onActivityStopped")
            }

            override fun onActivitySaveInstanceState(activity: Activity, 
            outState: Bundle) {

            }

            override fun onActivityDestroyed(activity: Activity) {
                FMSdk.getInstance().release()
                Log.d(TAG,"onActivityDestroyed")
            }

        })
    }

    //获取在初始化自身之前需要先初始化的其他Initializer 列表 ,
    // 这里有助于我们管理库的依赖顺序,比如我们的库依赖其他的库A,并且需要在
    // A之后进行初始化,就可以在这里配置
    //如果不需要依赖于其它组件,则可以返回一个空列表
    override fun dependencies()  = emptyList<Class<out Initializer<*>>>()
}

3.3 在我们库的AndroidManifest.xml中加入配置

定义好初始化的类后,我们需要在我们的库项目中声明一个provider,配置authorities为引用我们库的app的包名+“.androidx-startup”,然后定义一个<meta-data …/>节点,将我们定义的初始化类引用配置上去,这里我定义的类引用为:com.nolovr.core.fmsdk.engine.StartupInitializer。具体配置参考下面代码。

<application>
    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        tools:node="merge">
        <meta-data
            android:name="com.nolovr.core.fmsdk.engine.StartupInitializer"
            android:value="androidx.startup"
            />
    </provider>    
</application>

上面的步骤配置完后,开发者接入我们的库时就可以直接引入依赖,然后直接调用我们的库中的对应方法,不用再去Application下去做啥初始化操作啦

4.使用Startup组件的注意点

(1)使用Startup我们需要注意不能在StartupInitializer 的create()方法中做耗时操作,因为create方法是在主线程被调用的,如果做耗时操作会导致初始化时间变长,导致应用出现启动慢,黑白屏的问题。
(2)在引用库的主项目中不能使用tools:node=“remove” 的语句要求在合并 AndroidManifest 文件时移除自身否则自动初始化的功能就无法使用了。例如不能在主项目中做如下配置:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <meta-data
        android:name="com.nolovr.core.fmsdk.engine.StartupInitializer"
        android:value="androidx.startup"
        tools:node="remove" />
</provider>

或者是:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove" />

因为这样会导致我们的startup组件不生效,当然,如果是想自己手动初始化库的情况下除外。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

或许你更胜一筹呢

还记得刚出来时&#xff0c;一位前辈对我说过的一句话&#xff0c;“一定不要妄自菲薄”。说实话&#xff0c;一开始我并不知道这个成语的具体含义。后面百度才知道 妄自菲薄&#xff1a;过分地看轻自己 当时还没毕业&#xff0c;无论是从能力还是学识方面&#xff0c;我都不知…

C、C++、C#的区别概述

C、C、C#的区别概述 https://link.zhihu.com/?targethttps%3A//csharp-station.com/understanding-the-differences-between-c-c-and-c/文章翻译源于此链接 01、C语言 ​ Dennis Ritchie在1972年创造了C语言并在1978年公布。Ritchie设计C的初衷是用于开发新版本的Unix。在那之…

如何建立一套完善的销售管理体系?

如何建立一套完善的销售管理体系&#xff1f; 该提问下已有许多专业的回答&#xff0c;从多个角度为题主出谋划策&#xff1a;销售主管如何提升个人能力、销售团队如何管理、PDCA管理方法论、销售闭环……似乎都与硬性的个人能力挂钩&#xff0c;销售能力、管理能力等等。 或…

技术Leader:像李云龙一样打造学习型团队

今天跟大家分享一下怎么样构建一个学习型的团队。 首先对于计算机行业而言&#xff0c;不明而喻&#xff0c;我们要接受的东西真的太多了。我们接触的信息和变化也太多了。如果只是因循守旧&#xff0c;排斥新东西&#xff0c;那么我们被时代淘汰只是个时间问题。 想当年我大…

boost编译静态库

版本1_83_0 下载地址https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.zip 解压后根目录可见 参考方式&#xff1a;打开index.html 可通过此路径找到编译方法 进入getting started&#xff0c;右下角有linux和windows的下一步可选&#xff0…

IO流(二)

目录 一.文件拷贝 1.小文件拷贝 2.FileInputStream的读取问题 二.捕获异常 三.字符集 1.GBK 英文存储&#xff08;单字节&#xff09; 中文存储&#xff08;双字节&#xff09; 2.Unicode 3.乱码 原因 规避乱码的方式 四.字符流 FileReader 无参 有参 FileWrit…

pcl的polygonmesh在cloudcompare显示异常

一个polygonMesh文件在PCL显示是这样的: 把它保存成ply,然后用cc打开却是这样的: 这看起来像是某些三角面片没有被保存下来,实际上是因为保存的polygonmesh带有法线信息被pcl区分正反面,这些黑色的小三角它的法线朝向和绿色的不一样. 一个解决办法是清除法线.在cloudcompare选…

AI全栈大模型工程师(二十四)常用的超参

文章目录 七、先介绍几个常用的超参7.1、过拟合与欠拟合7.2、学习率调整策略八、自然语言处理常见的网络结构8.1、文本卷积神经网络 TextCNN8.2、循环神经网络 RNN8.3、Attention (for RNN)后记七、先介绍几个常用的超参 7.1、过拟合与欠拟合 奥卡姆剃刀: 两个处于竞争地位的…

防火墙访问控制、安全审计、网络设备防护检查表

1、访问控制类检查 2、安全审计类检查 3、网络设备防护类检查 原件&#xff1a; 防火墙标准检查表 分类 测评项 预期结果 访问控制 应在网络边界部署访问控制设备&#xff0c;启用访问控制功能 启用了访问控制规则 应能根据会话状态信息为数据流提供明确的允许/拒绝访…

thinkphp连接数据库mysql 报错问题

第一 看报错日志php如果是下面这个报错的话 就是mysql 数据库没有验证连接 ​​​​​​​[2023-12-13T09:57:0108:00][error] [10501]SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client 我们就可以去mysql 的文件检查 验证身份 使…

Nyquist Theorem(取样定理)

取样定理&#xff0c;又称为奈奎斯特定理&#xff08;Nyquist Theorem&#xff09;&#xff0c;是信号处理领域中一项至关重要的基本原理。它规定了对于连续时间信号&#xff0c;为了能够完全准确地还原出原始信号&#xff0c;即使是在离散时间下进行采样和再构建&#xff0c;都…

十大最好猫主食罐头有哪些品牌?最好猫主食罐头品牌推荐

很多人家里的哈基米是不是吃猫粮吃腻了&#xff0c;或者猫猫平时不喜欢喝水&#xff0c;又或者看猫猫太瘦了想入手几款猫罐头但是又愁于不会选择。而且现在猫罐头风这么大不知道选什么好~ 作为一个经营猫咖5年的老板&#xff0c;大促期间我总能捡漏&#xff0c;屯到一大波好吃…

Appium 自动化测试 —— Appium的环境搭建与设置流程!

1、Appium 环境搭建&#xff1a; 学习 appium 最大的难处之一在于环境的安装&#xff0c;安装流程比较繁琐&#xff0c;安装的工具和步骤也较多&#xff0c;以下是基于 Windows 系统下的 Android 手机端的安装流程。就像我们在用 Selenium 进行 web 自动化测试的时候一样&…

20章节多线程

20.1线程简介 世间有很多工作都是可以同时完成的。例如&#xff0c;人体可以同时进行呼吸、血液循环、思考问题等活用户既可以使用计算机听歌&#xff0c;也可以使用它打印文件。同样&#xff0c;计算机完全可以将多种活动同时进这种思想放在 Java 中被称为并发&#xff0c;而将…

前端八股文

前端八股文 目录 前端八股文1.css选择优先级&#xff1f;2.px与rem区别&#xff1f;3.重绘与重排的区别&#xff1f;4.元素水平垂直居中的方法&#xff1f;5.什么是闭包&#xff0c;闭包有什么特点&#xff1f;6.什么是事件委托&#xff1f;7.什么是原型链&#xff1f;8.new操作…

【Jenkins】Centos环境安装Jenkins(通过rpm安装)

在Centos操作系统中通过rpm安装Jenkins 参考官网 https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos 1、下载安装Jdk17 下载安装 # 更新您的系统&#xff0c;不一定需要 # sudo yum -y update # 安装将用于下载 Java 17 二进制文件的 wget 命令行工具。 s…

C++STL的stack和queue(超详解)

文章目录 前言stack栈的题目最小栈JZ31 栈的压入、弹出序列 stack的模拟实现queue的模拟实现 前言 栈和队列这一块其实有数据结构的基础&#xff0c;学起来非常简单。 stack 栈的成员函数就这么写&#xff0c;除了emplace其他都已经非常熟悉了。 stack没有迭代器吗&#xff…

10个前端开发不容错过的工具网站

作为开发人员&#xff0c;我们经常寻找合适的工具和资源来帮助日常开发工作。但是很多好用的工具网站尤其是国外的网站很多人都错过了。 这里我整理了一份包含 10 个网站的列表&#xff0c;这些网站或许可以帮助到作为前端开发者的你。 1、MDN Web 文档 MDN文档无疑是 Web 开…

【Linux】锁的简单封装以及原理解析

文章目录 一、锁的原理过程1&#xff1a;过程2过程3过程4 二、 锁的简单封装1.LockGuard.hpp2.使用1.正常锁的使用2.使用封装后的 总结 一、锁的原理 为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令,该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条…

让艺术触手可及!实时云渲染赋能真浪数字艺术馆首展

2023年5月18日&#xff0c;由真浪数字艺术和EZVR联合打造的真浪数字艺术馆首展–「破界交织」让艺术更自由&#xff0c;正式与大家相见。此次展览分为五个主题展馆&#xff0c;汇聚了来自全球各领域的19位青年数字艺术家一同探讨虚实共生、人机共生和万物共生的艺术创作。 真浪…