0
点赞
收藏
分享

微信扫一扫

Dagger2在SystemUI中的应用,我的腾讯Android面试经历分享

三千筱夜 2022-03-20 阅读 132

@Module和@Provides

  1. 通过 @Module 注解类
  2. 通过 @Provides 注解方法

Component管理Module,而Module是一个简单工厂模式,Module 里面的方法都是创建相应类实例的方法。 @Provides 用以标注 Module 类中的方法,它的作用是 标注该 Module 可以向外界提供的类的实例对象的方法

@Qualifier和@Named

  1. @Qualifier是限定符,是注解的注解
  2. @Named则是基于String的限定符

当我有两个相同的依赖(都继承某一个父类或者都是先某一个接口)可以提供给高层时,那么程序就不知道我们到底要提供哪一个依赖,因为它找到了两个。这时候我们就可以通过限定符为两个依赖分别打上标记,指定提供某个依赖。

@Scope和@Singleton

  1. @Scope是注解的注解, Scope机制可以保证在 Scope 标记的 Component 作用域内 ,类会保持单例 。
  2. @Singleton是@Scope的一个默认实现

@Sco

pe
@Documented
@Retention(RUNTIME)
public @interface Singleton {}

只要保证这个注解标记的 Component 在 App 进程中为单例的,并且得到正确的实现(被正确的标记到 类构造器 或 Module 中的 @Provides 标记的方法),那么它对应生成的类实例就是 单例的。

SystemUI中的dagger2使用

AppComponentFactory

SystemUI的application标签定义了一个appComponentFactory属性

<application

android:appComponentFactory=".SystemUIAppComponentFactory">

AppComponentFactory用于控制manifest清单文件里的组件的初始化

在manifest清单文件里的组件构建对象时会调用这些方法

47cebae4-ee7e-4966-9c64-52b4eccb02a5.png

SystemUIFactory

public Application instantiateApplicationCompat(
@NonNull ClassLoader cl, @NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Application app = super.instantiateApplicationCompat(cl, className);
if (app instanceof ContextInitializer) {
((ContextInitializer) app).setContextAvailableCallback(
context -> {
SystemUIFactory.createFromConfig(context);
SystemUIFactory.getInstance().getSysUIComponent().inject(
SystemUIAppComponentFactory.this);
}
);
}

return app;
}

在SystemUIApplication onCreate时回调 ContextAvailableCallback, 构建SystemUIFactory,并对它进行初始化

public static void createFromConfig(Context context, boolean fromTest) {
if (mFactory != null) {
return;
}

final String clsName = context.getString(R.string.config_systemUIFactoryComponent);
if (clsName == null || clsName.length() == 0) {
throw new RuntimeException(“No SystemUIFactory component configured”);
}

try {
Class<?> cls = null;
cls = context.getClassLoader().loadClass(clsName);
// 创建SystemUIFactory实例
mFactory = (SystemUIFactory) cls.newInstance();
// 初始化SystemUIFactory
mFactory.init(context, fromTest);
} catch (Throwable t) {
Log.w(TAG, "Error creating SystemUIFactory component: " + clsName, t);
throw new RuntimeException(t);
}
}

public void init(Context context, boolean fromTest)
throws ExecutionException, InterruptedException {

// 获取dagger组件
mRootComponent = buildGlobalRootComponent(context);

// 获取systemui的dagger组件
// And finally, retrieve whatever SysUI needs from WMShell and build SysUI.
SysUIComponent.Builder builder = mRootComponent.getSysUIComponent();
mSysUIComponent = builder.build();

// 构建Dependency实例并初始化
// Every other part of our codebase currently relies on Dependency, so we
// really need to ensure the Dependency gets initialized early on.
Dependency dependency = mSysUIComponent.createDependency();
dependency.start();
}

protected GlobalRootComponent buildGlobalRootComponent(Context context) {
return DaggerGlobalRootComponent.builder()
.context(context)
.build();
}

Dependency组件使用@Lazy标签懒加载: 首先构建LazyDependencyCreator放入mProviders,然后在真正使用dependency时调用createDependency进行创建

private final ArrayMap<Object, Object> mDependencies = new ArrayMap<>();
private final ArrayMap<Object, LazyDependencyCreator> mProviders = new ArrayMap<>();

@Inject Lazy mActivityStarter;
@Inject Lazy mBroadcastDispatcher;
@Inject Lazy mAsyncSensorManager;
@Inject Lazy mBluetoothController;

protected void start() {
// 构建LazyDependencyCreator放入mProviders
mProviders.put(TIME_TICK_HANDLER, mTimeTickHandler::get);
mProviders.put(BG_LOOPER, mBgLooper::get);
mProviders.put(MAIN_LOOPER, mMainLooper::get);
mProviders.put(MAIN_HANDLER, mMainHandler::get);
mProviders.put(MAIN_EXECUTOR, mMainExecutor::get);
mProviders.put(BACKGROUND_EXECUTOR, mBackgroundExecutor::get);
mProviders.put(ActivityStarter.class, mActivityStarter::get);
mProviders.put(BroadcastDispatcher.class, mBroadcastDispatcher::get);

// 获取dependency
private synchronized T getDependencyInner(Object key) {
@SuppressWarnings(“unchecked”)
T obj = (T) mDependencies.get(key);
if (obj == null) {
// 若未创建则创建
obj = createDependency(key);
mDependencies.put(key, obj);

}
return obj;
}

public T createDependency(Object cls) {
Preconditions.checkArgument(cls instanceof DependencyKey<?> || cls instanceof Class<?>);

@SuppressWarnings(“unchecked”)
LazyDependencyCreator provider = mProviders.get(cls);
if (provider == null) {

尾声

你不踏出去一步,永远不知道自己潜力有多大,千万别被这个社会套在我们身上的枷锁给捆住了,30岁我不怕,35岁我一样不怕,去做自己想做的事,为自己拼一把吧!不试试怎么知道你不行呢?

改变人生,没有什么捷径可言,这条路需要自己亲自去走一走,只有深入思考,不断反思总结,保持学习的热情,一步一步构建自己完整的知识体系,才是最终的制胜之道,也是程序员应该承担的使命。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)**

[外链图片转存中…(img-B0G0mLjA-1647760617614)]

举报

相关推荐

0 条评论