欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

spring java spring boot Dagger2和它在SystemUI上的應用

// AndroidManifest.xml

調(diào)用super得到Application實例之后向其注冊Context準備完畢的回調(diào),該回調(diào)會執(zhí)行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成功取得的回調(diào) ((ContextInitializer) app).setContextAvailableCallback( context -> { SystemUIFactory.createFromConfig(context); SystemUIFactory.getInstance().getRootComponent().inject( SystemUIAppComponentFactory.this); } ); }

return app; } … }

Application的onCreate()回調(diào)的時候意味著Context已準備完畢,接著執(zhí)行上述回調(diào)。

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(); … } }

回調(diào)將先創(chuàng)建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. 創(chuàng)建SystemUIFactory實例 mFactory = (SystemUIFactory) cls.newInstance(); mFactory.init(context); } }

private void init(Context context) { // 2. 取得SystemUI的Dagger組件實例 mRootComponent = buildSystemUIRootComponent(context); // 3. 創(chuàng)建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管理。但并不是在初始化的時候就緩存它們。而先將各實例對應的懶加載回調(diào)緩存進去。其后在各實例確實需要使用的時候通過注入的懶加載獲取和緩存。

public class Dependency { // 使用class作為key將對應實例緩存的Map private final ArrayMap mDependencies = new ArrayMap<>(); // 緩存實例的懶加載回調(diào)的Map private final ArrayMap 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); … }

// 根據(jù)class查詢緩存,尚未緩存的話通過懶加載回調(diào)獲取注入的實例并緩存 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創(chuàng)建好之后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實例。 它的構造函數(shù)注釋了@Inject。它依賴幾個Map參數(shù),比如StatusBar的Provider是注入到其中的SystemUI Map里。

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

// 依據(jù)名稱得到的class實例去查詢Provider實例,進而取得對應SystemUI的實例 private T resolve(String className, Map, 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構造器的參數(shù)竟有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(…); } }

SystemUI里DI關系圖

結語

回顧下依賴注入技術的必要性。

代碼的復用:通過參數(shù)傳遞復用實例減少樣板代碼測試的方便:通過注入模擬參數(shù)可以快速測試邏輯耦合度降低:類專注于自己的邏輯互相之間只通過參數(shù)連接

是否一定非要選擇Dagger2這種自動方案呢?我覺得依據(jù)對項目的了解程度決定。 因為無論是采用手動還是自動的依賴注入方案,都需要我們理清各模塊各類之前的關系,正確地定位每個類的角色,把握每個實例的作用域。 自我介紹一下,小編13年上海交大畢業(yè),曾經(jīng)在小公司待過,也去過華為、OPPO等大廠,18年進入阿里一直到現(xiàn)在。

深知大多數(shù)初中級Android工程師,想要提升技能,往往是自己摸索成長或者是報班學習,但對于培訓機構動則近萬的學費,著實壓力不小。自己不成體系的自學效果低效又漫長,而且極易碰到天花板技術停滯不前!

因此收集整理了一份《2024年Android移動開發(fā)全套學習資料》,初衷也很簡單,就是希望能夠幫助到想自學提升又不知道該從何學起的朋友,同時減輕大家的負擔。

既有適合小白學習的零基礎資料,也有適合3年以上經(jīng)驗的小伙伴深入學習提升的進階課程,基本涵蓋了95%以上Android開發(fā)知識點,真正體系化!

由于文件比較大,這里只是將部分目錄截圖出來,每個節(jié)點里面都包含大廠面經(jīng)、學習筆記、源碼講義、實戰(zhàn)項目、講解視頻,并且會持續(xù)更新!

如果你覺得這些內(nèi)容對你有幫助,可以掃碼獲?。。。▊渥ⅲ篈ndroid)

總結

最后對于程序員來說,要學習的知識內(nèi)容、技術有太多太多,要想不被環(huán)境淘汰就只有不斷提升自己,從來都是我們?nèi)ミm應環(huán)境,而不是環(huán)境來適應我們!

這里附上上述的技術體系圖相關的幾十套騰訊、頭條、阿里、美團等公司20年的面試題,把技術點整理成了視頻和PDF(實際上比預期多花了不少精力),包含知識脈絡 + 諸多細節(jié),由于篇幅有限,這里以圖片的形式給大家展示一部分。

相信它會給大家?guī)砗芏嗍斋@:

當程序員容易,當一個優(yōu)秀的程序員是需要不斷學習的,從初級程序員到高級程序員,從初級架構師到資深架構師,或者走向管理,從技術經(jīng)理到技術總監(jiān),每個階段都需要掌握不同的能力。早早確定自己的職業(yè)方向,才能在工作和能力提升中甩開同齡人。

《Android學習筆記總結+移動架構視頻+大廠面試真題+項目實戰(zhàn)源碼》,點擊傳送門即可獲?。?/p>

幅有限,這里以圖片的形式給大家展示一部分。

相信它會給大家?guī)砗芏嗍斋@: [外鏈圖片轉存中…(img-Sr0NXY4m-1711814039405)]

[外鏈圖片轉存中…(img-3xqQpydW-1711814039405)]

當程序員容易,當一個優(yōu)秀的程序員是需要不斷學習的,從初級程序員到高級程序員,從初級架構師到資深架構師,或者走向管理,從技術經(jīng)理到技術總監(jiān),每個階段都需要掌握不同的能力。早早確定自己的職業(yè)方向,才能在工作和能力提升中甩開同齡人。

《Android學習筆記總結+移動架構視頻+大廠面試真題+項目實戰(zhàn)源碼》,點擊傳送門即可獲?。?/p>

參考閱讀

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉載請注明,如有侵權,聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/18911845.html

發(fā)布評論

您暫未設置收款碼

請在主題配置——文章設置里上傳

掃描二維碼手機訪問

文章目錄