StartUp是为了App的启动提供的一套简单、高效的初始化方案。
在项目中会需要用到很多的第三方库,而很多第三方库都提供了显示的调用初始化接口,需要在Application中进行初始化,并获取到Application的Context。
于是乎,Application中的代码就可能会变成这个样子:
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
A.initialize(this)
B.initialize(this)
C.initialize(this)
...
}
...
}
随着引入的第三方库越来越多,Application中的代码也是越来越庞大。
于是乎,有些更加聪明的库设计者,他们想到了一种非常巧妙的办法来避免显示的调用初始化接口,而是可以自动调用初始化接口,这种办法就是借助ContentProvider。
ContentProvider作为Android四大组件之一,其主要作用是跨应用程序共享数据。
然而这些第三方库并没有打算使用ContentProvider来跨应用程序共享数据,只是准备使用它拿到Context进行初始化而已。在APP的启动流程中,有一步就是要执行到程序中所有注册过的ContentProvider的onCreate方法,所以这些第三方库的初始化就默默自动完成了。
这种设计方式可以将库的用法进一步简化,不需要主动去调用初始化接口,而是将这个工作在背后悄悄自动完成了,给集成库的开发者们带来了很大的便利。很多库都用到了这种方法,比如Facebook,Firebase。
但是呢,看上去如此巧妙的技术方案,有一个很大的缺点就是,ContentProvider会增加许多额外的耗时。因为不同的库就定义了不同的ContentProvider类,多了这么多ContentProvider,ContentProvider作为四大组件之一,启动也是耗时的,自然也就增加App启动消耗的时间了。
这时候就需要App Startup来对此情况进行优化了。
首先来看一下官网对于Startup的简介:
The App Startup library provides a straightforward, performant way to initialize components at application startup. Both library developers and app developers can use App Startup to streamline startup sequences and explicitly set the order of initialization.
Instead of defining separate content providers for each component you need to initialize, App Startup allows you to define component initializers that share a single content provider. This can significantly improve app startup time.
主要说到了两点特性:
其实,App Startup内部也是创建了一个ContentProvider,并提供了一套用于初始化的标准。然后对于其他第三方库来说,就不需要再自己创建ContentProvider了,都按Startup这套标准进行实现就行了。同时Startup还提供了可以设置初始化顺序。
首先,引入库:
implementation 'androidx.startup:startup-runtime:1.1.1'
然后定义一个用于执行初始化的Initializer,并实现App Startup库的Initializer接口:
class ARouterInitializer : Initializer<String> {
override fun create(context: Context): String {
ARouter.init(context.applicationContext as Application)
return "ARouterInit"
}
override fun dependencies(): List<Class<out Initializer<*>>> {
return emptyList()
}
}
实现Initializer接口要求重写两个方法,在create()方法中可以进行初始化操作,这里以ARouter发初始化为例。
dependencies()方法表示,当前的初始化是否还依赖于其他的Initializer,如果有的话,就在这里进行配置,App Startup会保证先初始化依赖的Initializer,然后才会初始化当前,这样就可以设置初始化顺序了。当然,绝大多数的情况下,初始化操作都是不会依赖于其他Initializer的,所以通常直接返回一个emptyList()就可以了。
最后,在AndroidManifest.xml中进行配置,这里需要严格按照Startup的配置规范:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="com.example.base.ARouterInitializer"
android:value="androidx.startup" />
</provider>
只有meta-data中的android:name部分需要指定成自定义的Initializer的全路径类名,其他部分都是不能修改的,否则App Startup库可能会无法正常工作。
tools:node="merge"标签就是用来合并所有申明了InitializationProvider的ContentProvider。
如果不希望初始化在应用启动的时候自动初始化,App Startup也是提供了手动调用初始化的方法。
<!-- 禁用所有InitializationProvider组件初始化 -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
<!-- 禁用单个InitializationProvider组件初始化 -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="com.example.base.ARouterInitializer"
tools:node="remove" />
</provider>
使用tools:node="remove"标签,这个标签用于告诉manifest merger tool,在最后打包成APK时,将所有该名称的节点全部删除。可以禁用所有InitializationProvider组件初始化,也可以禁用单个InitializationProvider组件初始化。
AppInitializer.getInstance(this).initializeComponent(ARouterInitializer::class.java)
然后再手动调用App Startup提供的初始化方法。
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路