Dagger2和它在SystemUI上的应用,附答案

这篇具有很好参考价值的文章主要介绍了Dagger2和它在SystemUI上的应用,附答案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

@Override
public Application instantiateApplicationCompat(
@NonNull ClassLoader cl, @NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Application app = super.instantiateApplicationCompat(cl, className);
if (app instanceof ContextInitializer) {
// 注册Context成功取得的回调
((ContextInitializer) app).setContextAvailableCallback(
context -> {
SystemUIFactory.createFromConfig(context);
SystemUIFactory.getInstance().getRootComponent().inject(
SystemUIAppComponentFactory.this);
}
);
}

return app;
}

}

Application的onCreate()回调的时候意味着Context已准备完毕,接着执行上述回调。

public class SystemUIApplication extends Application implements
SystemUIAppComponentFactory.ContextInitializer {

@Override
public void setContextAvailableCallback(
SystemUIAppComponentFactory.ContextAvailableCallback callback) {
mContextAvailableCallback = callback;
}

@Override
public void onCreate() {

log.traceBegin(“DependencyInjection”);
mContextAvailableCallback.onContextAvailable(this);★
mRootComponent = SystemUIFactory.getInstance().getRootComponent();
mComponentHelper = mRootComponent.getContextComponentHelper();

}
}

回调将先创建SystemUIFactory实例,并初始化SystemUI App的Dagger组件。之后初始化DI子组件并向Dependency实例注入依赖。

public class SystemUIFactory {
public static void createFromConfig(Context context) {

try {
Class<?> cls = null;
cls = context.getClassLoader().loadClass(clsName);
// 1. 创建SystemUIFactory实例
mFactory = (SystemUIFactory) cls.newInstance();
mFactory.init(context);
}
}

private void init(Context context) {
// 2. 取得SystemUI的Dagger组件实例
mRootComponent = buildSystemUIRootComponent(context);
// 3. 创建Dependency实例并绑定到DependencyInjector子组件中
Dependency dependency = new Dependency();
mRootComponent.createDependency().createSystemUI(dependency);
// 4. 初始化Dependency
dependency.start();
}

// 初始化Dagger组件
protected SystemUIRootComponent buildSystemUIRootComponent(Context context) {
return DaggerSystemUIRootComponent.builder()
.dependencyProvider(new DependencyProvider())
.contextHolder(new ContextHolder(context))
.build();
}

}

Dependency类里掌管着各式各样的依赖,被依赖的各实例通过Map管理。但并不是在初始化的时候就缓存它们。而先将各实例对应的懒加载回调缓存进去。其后在各实例确实需要使用的时候通过注入的懒加载获取和缓存。

public class Dependency {
// 使用class作为key将对应实例缓存的Map
private final ArrayMap<Object, Object> mDependencies = new ArrayMap<>();
// 缓存实例的懒加载回调的Map
private final ArrayMap<Object, LazyDependencyCreator> mProviders = new ArrayMap<>();

protected void start() {
mProviders.put(ActivityStarter.class, mActivityStarter::get);
mProviders.put(Recents.class, mRecents::get);
mProviders.put(StatusBar.class, mStatusBar::get);
mProviders.put(NavigationBarController.class, mNavigationBarController::get);

}

// 根据class查询缓存,尚未缓存的话通过懒加载回调获取注入的实例并缓存
private synchronized T getDependencyInner(Object key) {
T obj = (T) mDependencies.get(key);
if (obj == null) {
obj = createDependency(key);
mDependencies.put(key, obj);
if (autoRegisterModulesForDump() && obj instanceof Dumpable) {
mDumpManager.registerDumpable(obj.getClass().getName(), (Dumpable) obj);
}
}
return obj;
}

protected T createDependency(Object cls) {
Preconditions.checkArgument(cls instanceof DependencyKey<?> || cls instanceof Class<?>);
LazyDependencyCreator provider = mProviders.get(cls);
return provider.createDependency();
}

private interface LazyDependencyCreator {
T createDependency();
}
}

Application创建好之后SystemUI的主Service将启动起来,并逐个启动其他Service。

public class SystemUIService extends Service {

@Override
public void onCreate() {
super.onCreate();
// Start all of SystemUI
((SystemUIApplication) getApplication()).startServicesIfNeeded();

}
}

通过ContextComponentHelper解析预设的service类名得到实例并启动。

public class SystemUIApplication {
public void startServicesIfNeeded() {
String[] names = SystemUIFactory.getInstance().getSystemUIServiceComponents(getResources());
startServicesIfNeeded(/* metricsPrefix= */ “StartServices”, names);
}

private void startServicesIfNeeded(String metricsPrefix, String[] services) {

final int N = services.length;
for (int i = 0; i < N; i++) {
String clsName = services[i];
try {
// 从ContextComponentHelper里获取对应的实例
SystemUI obj = mComponentHelper.resolveSystemUI(clsName);
if (obj == null) {
Constructor constructor = Class.forName(clsName).getConstructor(Context.class);
obj = (SystemUI) constructor.newInstance(this);
}
mServices[i] = obj;
}

mServices[i].start();

}
mRootComponent.getInitController().executePostInitTasks();
}
}

配置的Service列表。

// config.xml


com.android.systemui.recents.Recents
com.android.systemui.volume.VolumeUI
com.android.systemui.stackdivider.Divider
com.android.systemui.statusbar.phone.StatusBar ★

ContextComponentHelper单例已声明由Dagger组件提供。

@Singleton
@Component(modules = {…})
public interface SystemUIRootComponent {

/**

  • Creates a ContextComponentHelper.
    */
    @Singleton
    ContextComponentHelper getContextComponentHelper();
    }

模块SystemUIModule负责注入ContextComponentHelper实例,实际注入的是ContextComponentResolver实例。

@Module(…)
public abstract class SystemUIModule {

/** */
@Binds
public abstract ContextComponentHelper bindComponentHelper(
ContextComponentResolver componentHelper);
}

ContextComponentResolver用于解析Activity和Service等实例,通过class实例从Map查询得到的Provider里取得对应的Service实例。 它的构造函数注释了@Inject。它依赖几个Map参数,比如StatusBar的Provider是注入到其中的SystemUI Map里。

@Singleton
public class ContextComponentResolver implements ContextComponentHelper {
@Inject
ContextComponentResolver(Map<Class<?>, Provider> activityCreators, Map

// 依据名称得到的class实例去查询Provider实例,进而取得对应SystemUI的实例
private T resolve(String className, Map<Class<?>, Provider> creators) { try { Class<?> clazz = Class.forName(className);
Provider provider = creators.get(clazz);
return provider == null ? null : provider.get();
} catch (ClassNotFoundException e) {
return null;
}
}
}

在SystemUIBinder的Module里声明了以ClassKey为StatusBar.class,value由StatusBarPhoneModule模块注入到Map里。而Provider#get()的实例将拿到provideStatusBar注入的实例。(StatusBar构造器的参数竟有76个之多,简直恐怖。。。)

@Module(includes = {RecentsModule.class, StatusBarModule.class…})
public abstract class SystemUIBinder {
/** Inject into StatusBar. */
@Binds
@IntoMap
@ClassKey(StatusBar.class)
public abstract SystemUI bindsStatusBar(StatusBar sysui);

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
Dagger2和它在SystemUI上的应用,附答案,2024年程序员学习,spring,java,spring boot
Dagger2和它在SystemUI上的应用,附答案,2024年程序员学习,spring,java,spring boot
Dagger2和它在SystemUI上的应用,附答案,2024年程序员学习,spring,java,spring boot
Dagger2和它在SystemUI上的应用,附答案,2024年程序员学习,spring,java,spring boot
Dagger2和它在SystemUI上的应用,附答案,2024年程序员学习,spring,java,spring boot
Dagger2和它在SystemUI上的应用,附答案,2024年程序员学习,spring,java,spring boot
Dagger2和它在SystemUI上的应用,附答案,2024年程序员学习,spring,java,spring boot

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
Dagger2和它在SystemUI上的应用,附答案,2024年程序员学习,spring,java,spring boot

e05a14868a3f0fd6ac81d625c.png)

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-cEb31ZmD-1711642599592)]文章来源地址https://www.toymoban.com/news/detail-844862.html

到了这里,关于Dagger2和它在SystemUI上的应用,附答案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 车载应用开发指南(3) - SystemUI 详解

    Android 车载应用开发指南系列文章 Android 车载应用开发指南(1)- 车载操作系统全解析 Android 车载应用开发指南(2)- 应用开发入门 Android 车载应用开发指南(3)- SystemUI 详解 SystemUI 全称 System User Interface ,直译过来就是 系统级用户交互界面 ,在 Android 系统中由 SystemUI 负责

    2024年02月19日
    浏览(40)
  • 车载Android应用开发与分析 - 初试 SystemUI Plugin

    在前面的视频、文章中我们介绍完了整个车载Android应用开发所需要的基础知识: 【视频文稿】车载Android应用开发与分析 - 走进车载操作系统 - 掘金 【视频文稿】车载Android应用开发与分析 - AOSP的下载与编译 - 掘金 【视频文稿】车载Android应用开发与分析 - 开发系统应用 - 掘

    2024年02月02日
    浏览(37)
  • Android 12 源码分析 —— 应用层 一(SystemUI准备篇)

    在接下来的时间中,将会使用Pixel 3(blueline)作为研究对象,选用AOSP的android-12.0.0_r34分支作源代码。 先从android的应用层进行探析,然后慢慢深入android的framework,接着进入android的hal层,最后以android的linux内核结束,期间可能会穿插一些其他文章如android的art虚拟机分析等。 本文

    2024年02月12日
    浏览(44)
  • Android 12 源码分析 —— 应用层 二(SystemUI大体组织和启动过程)

    在前一篇文章中,我们介绍了SystemUI怎么使用IDE进行编辑和调试。这是分析SystemUI的最基础,希望读者能尽量掌握。 本篇文章,将会介绍SystemUI的大概组织架构,以及它的启动过程。本篇文章读完,将会知道: SystemUI为什么选择使用Dagger2 SystemUI怎么新建一个模块 SystemUI的启动

    2024年02月06日
    浏览(75)
  • Android 12 源码分析 —— 应用层 四(SystemUI的基本布局设计及其基本概念)

    更新历史 日期 内容 1 2023-9-11 增加文中提及的渐变动画的效果图 在上两篇文章中,我们介绍SystemUI的启动过程,以及基本的组件依赖关系。基本的依赖关系请读者一定要掌握,因为后面的文章,将会时常出现这些依赖关系的使用,届时将会一笔带过,而不会详细说明他们的实

    2024年02月08日
    浏览(64)
  • A Beginner‘s Guide to Apache Kafka: 什么是Kafka、它为什么如此受欢迎、它在哪些场景下可以应用、以及一些基本概念和术语

    作者:禅与计算机程序设计艺术 Apache Kafka(以下简称Kafka)是一个开源分布式流处理平台,它被设计用来实时传输大量的数据,从而能够实时的对数据进行处理并提取价值。本文通过梳理,引导读者了解什么是Kafka、它为什么如此受欢迎、它在哪些场景下可以应用、以

    2024年02月09日
    浏览(60)
  • 【Android】Dagger和Hilt新手快速入门

    什么是Dagger和Hilt Dagger和Hilt都是安卓端的依赖注入框架 通过注解生成的方式,来取代手动创建对象的方式,来管理对象和其作用域 Dagger是Square公司出品的,而Hilt是由Google公司在Dagger的基础上优化而来 配置项目级别gradle 配置模块级别gradle Hilt使用方式 由于Hilt是个Dagger基础上

    2024年02月12日
    浏览(75)
  • Android之Dagger&Hilt依赖注入使用指南

    Dagger2 是一个 Dependency Injection(DI) 依赖注入框架。它提供给 Java 和 Android 使用, 主要用于模块间解耦、提高代码的健壮性和可维护性 。 使用了 IOC (控制反转)的思想,在编译阶段使用 APT 利用 Java 注解生成 Java 代码,然后结合部分手写代码来完整依赖注入工作。 运行前需

    2024年02月07日
    浏览(37)
  • 定积分在几何上的应用

    目录 定积分的元素法  平面图形的面积问题:  ​编辑  极坐标方程  例题: 旋转体的体积:  平面曲线的弧长:  弧长的三个公式:  例题:    例如:  步骤1:我们先把区间a,b分成n个区间 步骤2:我们在一个区间中设置一点ξ点,用这一点的函数值代替区间内部所有的

    2024年02月01日
    浏览(64)
  • sshpiper 在 Kubernetes 上的应用

    GitHub Repo 一个反向代理目标服务器的 proxy,客户端想请求某个 ssh 服务器,直接请求的是 sshpiper 服务,再经由 sshpiper 服务转发到对应的 ssh 服务器,相当于一个中间人。 一开始并不理解这种组件的用处,但实际用了之后感觉还是蛮有意思的。 设想有这样一种场景,你有多个

    2024年02月16日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包