赞
踩
// AndroidManifest.xml
<application
android:name=“.SystemUIApplication”
…
tools:replace=“android:appComponentFactory”
android:appComponentFactory=“.SystemUIAppComponentFactory”>
调用super得到Application实例之后向其注册Context准备完毕的回调,该回调会执行SystemUIFactory和DI组件的初始化。
public class SystemUIAppComponentFactory extends AppComponentFactory {
@Inject
public ContextComponentHelper mComponentHelper;
…
@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 {
…
/**
模块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);
…
}
@Module(includes = {StatusBarPhoneModule.class…})
public interface StatusBarModule {
}
@Module(includes = {StatusBarPhoneDependenciesModule.class})
public interface StatusBarPhoneModule {
@Provides
@Singleton
static StatusBar provideStatusBar(
Context context,
NotificationsController notificationsController,
LightBarController lightBarController,
AutoHideController autoHideController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
StatusBarIconController statusBarIconController,
…) {
return new StatusBar(…);
}
}
回顾下依赖注入技术的必要性。
是否一定非要选择Dagger2这种自动方案呢?我觉得依据对项目的了解程度决定。
因为无论是采用手动还是自动的依赖注入方案,都需要我们理清各模块各类之前的关系,正确地定位每个类的角色,把握每个实例的作用域。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
最后对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
[外链图片转存中…(img-Sr0NXY4m-1711814039405)]
[外链图片转存中…(img-3xqQpydW-1711814039405)]
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。