写点什么

Dagger2 在 SystemUI 中的应用

用户头像
Android架构
关注
发布于: 59 分钟前

return app;}


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


src/com/android/systemui/SystemUIFactory.java


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();// 初始化 SystemUIFactorymFactory.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 进行创建


src/com/android/systemui/Dependency.java


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


@Inject Lazy<ActivityStarter> mActivityStarter;@Inject Lazy<BroadcastDispatcher> mBroadcastDispatcher;@Inject Lazy<AsyncSensorManager> mAsyncSensorManager;@Inject Lazy<BluetoothController> mBluetoothController;


protected void start() {// 构建 LazyDependencyCreator 放入 mProvidersmProviders.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);...


// 获取 dependencyprivate synchronized <T> 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> T createDependency(Object cls) {Preconditions.checkArgument(cls instanceof DependencyKey<?> || cls instanceof Class<?>);


@SuppressWarnings("unchecked")LazyDependencyCreator<T> provider = mProviders.get(cls);if (provider == null) {throw new IllegalArgumentException("Unsupported dependency " + cls


  • ". " + mProviders.size() + " providers known.");}


// 这里调用的就是 lazy.get()return provider.createDependency();}


private interface LazyDependencyCreator<T> {T createDependency();}

ContextComponentResolver

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


src/com/android/systemui/SystemUIService.java


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


ContextComponentHelper 声明在 dagger 组件中获取,实现类是 ContextComponentResolver


src/com/android/systemui/SystemUIApplication.java


private void startServicesIfNeeded(String metricsPrefix, String[] services) {...final int N = services.length;for (int i = 0; i < N; i++) {String clsName = services[i];if (DEBUG) Log.d(TAG, "loading: " + clsName);log.traceBegin(metricsPrefix + clsName);long ti = System.currentTimeMillis();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;} catch (ClassNotFoundException| NoSuchMethodException| IllegalAccessException| InstantiationException| InvocationTargetException ex) {throw new RuntimeException(ex);}


if (DEBUG) Log.d(TAG, "running: " + mServices[i]);// 调用 SystemUI 组件的 start()方法 mServices[i].start();


ContextComponentHelper 声明在 dagger 组件中获取,实现类是 ContextComponentResolver


src/com/android/systemui/dagger/SysUIComponent.java


@SysUISingletonContextComponentHelper getContextComponentHelper();


@Overridepublic SystemUI resolveSystemUI(String className) {return resolve(className, mSystemUICreators);}


private <T> T resolve(String className, Map<Class<?>, Provider<T>> creators) {try {Class<?> clazz = Class.forName(className);Provider<T> provider = creators.get(clazz);return provider == null ? null : provider.get();} catch (ClassNotFoundException e) {return null;}}

MultiBinding

ContextComponentResolver 的构建方法里,activity、service、systemui 组件、recents 组件、broadcastreceiver 作为参数放到 Map 里储存。


src/com/android/systemui/dagger/ContextComponentResolver.java


@SysUISingletonpublic class ContextComponentResolver implements ContextComponentHelper {priv


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ate final Map<Class<?>, Provider<Activity>> mActivityCreators;private final Map<Class<?>, Provider<Service>> mServiceCreContextComponentHelper 声明在 dagger 组件中获取,实现类是 ContextComponentResolverators;private final Map<Class<?>, Provider<SystemUI>> mSystemUICreators;private final Map<Class<?>, Provider<RecentsImplementation>> mRecentsCreators;private final Map<Class<?>, Provider<BroadcastReceiver>> mBroadcastReceiverCreators;


@InjectContextComponentResolver(Map<Class<?>, Provider<Activity>> activityCreators,Map<Class<?>, Provider<Service>> serviceCreators,Map<Class<?>, Provider<SystemUI>> systemUICreators,Map<Class<?>, Provider<RecentsImplementation>> recentsCreators,Map<Class<?>, Provider<BroadcastReceiver>> broadcastReceiverCreators) {mActivityCreators = activityCreators;mServiceCreators = serviceCreators;mSystemUICreators = systemUICreators;mRecentsCreators = recentsCreators;mBroadcastReceiverCreators = broadcastReceiverCreators;}


构建的来源是 systemuicomponent 的各个 module,使用 @IntoMap 和 @ClassKey 进行 MultiBinding


以 SystemUI 组件为例


src/com/android/systemui/dagger/SystemUIBinder.java


@Module(includes = {RecentsModule.class, StatusBarModule.class, KeyguardModule.class})public abstract class SystemUIBinder {/** Inject into AuthController. */@Binds@IntoMap@ClassKey(AuthController.class)public abstract SystemUI bindAuthController(AuthController service);


/** Inject into GarbageMonitor.Service. */@Binds@IntoMap@ClassKey(GarbageMonitor.Service.class)public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service sysui);


/** Inject into GlobalActionsComponent. */

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Dagger2在SystemUI中的应用