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

目錄

spring java spring boot Dagger2和它在SystemUI上的應(yīng)用

// AndroidManifest.xml

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

return app; } … }

Application的onCreate()回調(diào)的時(shí)候意味著Context已準(zhǔn)備完畢,接著執(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實(shí)例,并初始化SystemUI App的Dagger組件。之后初始化DI子組件并向Dependency實(shí)例注入依賴。

public class SystemUIFactory { public static void createFromConfig(Context context) { … try { Class cls = null; cls = context.getClassLoader().loadClass(clsName); // 1. 創(chuàng)建SystemUIFactory實(shí)例 mFactory = (SystemUIFactory) cls.newInstance(); mFactory.init(context); } }

private void init(Context context) { // 2. 取得SystemUI的Dagger組件實(shí)例 mRootComponent = buildSystemUIRootComponent(context); // 3. 創(chuàng)建Dependency實(shí)例并綁定到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類里掌管著各式各樣的依賴,被依賴的各實(shí)例通過(guò)Map管理。但并不是在初始化的時(shí)候就緩存它們。而先將各實(shí)例對(duì)應(yīng)的懶加載回調(diào)緩存進(jìn)去。其后在各實(shí)例確實(shí)需要使用的時(shí)候通過(guò)注入的懶加載獲取和緩存。

public class Dependency { // 使用class作為key將對(duì)應(yīng)實(shí)例緩存的Map private final ArrayMap mDependencies = new ArrayMap<>(); // 緩存實(shí)例的懶加載回調(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查詢緩存,尚未緩存的話通過(guò)懶加載回調(diào)獲取注入的實(shí)例并緩存 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將啟動(dòng)起來(lái),并逐個(gè)啟動(dòng)其他Service。

public class SystemUIService extends Service { … @Override public void onCreate() { super.onCreate(); // Start all of SystemUI ((SystemUIApplication) getApplication()).startServicesIfNeeded(); … } }

通過(guò)ContextComponentHelper解析預(yù)設(shè)的service類名得到實(shí)例并啟動(dòng)。

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里獲取對(duì)應(yīng)的實(shí)例 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負(fù)責(zé)注入ContextComponentHelper實(shí)例,實(shí)際注入的是ContextComponentResolver實(shí)例。

@Module(…) public abstract class SystemUIModule { … /** */ @Binds public abstract ContextComponentHelper bindComponentHelper( ContextComponentResolver componentHelper); }

ContextComponentResolver用于解析Activity和Service等實(shí)例,通過(guò)class實(shí)例從Map查詢得到的Provider里取得對(duì)應(yīng)的Service實(shí)例。 它的構(gòu)造函數(shù)注釋了@Inject。它依賴幾個(gè)Map參數(shù),比如StatusBar的Provider是注入到其中的SystemUI Map里。

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

// 依據(jù)名稱得到的class實(shí)例去查詢Provider實(shí)例,進(jìn)而取得對(duì)應(yīng)SystemUI的實(shí)例 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()的實(shí)例將拿到provideStatusBar注入的實(shí)例。(StatusBar構(gòu)造器的參數(shù)竟有76個(gè)之多,簡(jiǎn)直恐怖。。。)

@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關(guān)系圖

結(jié)語(yǔ)

回顧下依賴注入技術(shù)的必要性。

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

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

深知大多數(shù)初中級(jí)Android工程師,想要提升技能,往往是自己摸索成長(zhǎng)或者是報(bào)班學(xué)習(xí),但對(duì)于培訓(xùn)機(jī)構(gòu)動(dòng)則近萬(wàn)的學(xué)費(fèi),著實(shí)壓力不小。自己不成體系的自學(xué)效果低效又漫長(zhǎng),而且極易碰到天花板技術(shù)停滯不前!

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

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

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

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

總結(jié)

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

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

相信它會(huì)給大家?guī)?lái)很多收獲:

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

《Android學(xué)習(xí)筆記總結(jié)+移動(dòng)架構(gòu)視頻+大廠面試真題+項(xiàng)目實(shí)戰(zhàn)源碼》,點(diǎn)擊傳送門即可獲??!

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

相信它會(huì)給大家?guī)?lái)很多收獲: [外鏈圖片轉(zhuǎn)存中…(img-Sr0NXY4m-1711814039405)]

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

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

《Android學(xué)習(xí)筆記總結(jié)+移動(dòng)架構(gòu)視頻+大廠面試真題+項(xiàng)目實(shí)戰(zhàn)源碼》,點(diǎn)擊傳送門即可獲??!

參考閱讀

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

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

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

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

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問(wèn)

文章目錄