您好,登錄后才能下訂單哦!
組件化開(kāi)發(fā)過(guò)程中,隨著組件越來(lái)越多,組件的之前的交互就會(huì)變得非常的復(fù)雜,此時(shí)組件間通信變得尤其的重要,
ServicePool
就是為組件化而生,用最簡(jiǎn)單的方式進(jìn)行組件間通信。
使用依賴注入,按需靈活注入組件。同時(shí)支持組件熱插拔,達(dá)到組件即插即用的效果??膳渲媒M件生命周期,做到組件按需創(chuàng)建和及時(shí)回收,充分利用懶加載的思想,有效解決組件初始化耗時(shí)導(dǎo)致的
app
啟動(dòng)速度問(wèn)題。
ServicePool
包含有
Activity
路由, 組件路由等等最常用的組件化能力。除此之外,組件化開(kāi)發(fā)過(guò)程中有沒(méi)有遇到過(guò)想使用某個(gè)已有的類,比如一個(gè)工具類的時(shí)候,發(fā)現(xiàn)這個(gè)工具類在當(dāng)前類的上層,無(wú)法直接依賴和引用,而修改這個(gè)工具類的層級(jí)又會(huì)牽一發(fā)而動(dòng)全身的問(wèn)題?有沒(méi)有想要一個(gè)差異響應(yīng)的能力,在不同的組件中或者環(huán)境下,有著不同的響應(yīng)方式?有沒(méi)有想要一個(gè)自適應(yīng)場(chǎng)景的能力,自動(dòng)適應(yīng)當(dāng)前環(huán)境(比如
Java
還是
Android
環(huán)境,比如
Debug
環(huán)境還是
Release
環(huán)境等等),從而使用最合適的功能。又有沒(méi)有想過(guò)如何讓組件做到像USB接口一樣插上就能直接使用,拔掉也不影響主體功能的即插即用的效果。等等...。下面就來(lái)具體介紹一下這個(gè)組件化神器——
ServicePool
!
如上圖所示:
A
,
B
是兩個(gè)互不依賴的組件,
A
,
B
不能直接通信A
,
B
分別通過(guò)
AService
,
BService
對(duì)外提供服務(wù)A
,
B
的接口協(xié)議存放在組件服務(wù)池
pool
, 分別是接口IA, IBServicePool
申請(qǐng), 由
ServicePool
創(chuàng)建并返回
aService
給組件B, 此時(shí)組件
b
可以使用
aService
的服務(wù)了A
使用
IB
向
ServicePool
申請(qǐng)
bService
aService
,
bService
由
ServicePool
創(chuàng)建和管理Service
對(duì)象的優(yōu)先級(jí)生命周期可以通過(guò)
@Service
注解配置/** * 服務(wù)池pool中 * * IA.java */ public interface IA { void aName(); } /** * 服務(wù)池pool * * IB.java */ public interface IB { void bName(); }
/** * 組件A * * AService.java */ @Service public class AService implements IA { @Override public String aName() { return "A Service"; } }
/** * 組件B * * BService.java */ @Service public class BService implements IB { @Override public String bName() { return "B Service"; } }
組件A中執(zhí)行: IB b = ServicePool.getService(IB.class); System.out.println("I'm A Service, I can get " + b.bName()); 輸出: I'm A Service, I can get B Service 組件B中執(zhí)行: IA a = ServicePool.getService(IA.class); System.out.println("I'm B Service, I can get " + a.aName()); 輸出: I'm B Service, I can get A Service
由于所有示例涉及到依賴注入,這里提前對(duì)
ServicePool
的依賴注入做個(gè)說(shuō)明。和其他注入框架不同,
ServicePool
的注入方式很簡(jiǎn)單,只有一種注入方式就是直接通過(guò)類注入。
@Service public class AImpl implements IA { @Override public String aName() { return "A Impl" } }
ServicePool
就是一個(gè)注入容器。最后通過(guò)
ServicePool
.
getService(IA.class)
方法注入對(duì)象, 也可以通過(guò)
@Service
標(biāo)記成員變量的方式注入,這兩個(gè)方法等價(jià)。
public class MainActivity extends AppcompatActivity { /** * 等價(jià)于 * IA = ServicePool.getService(IA.class); */ @Service private IA a; @Override public void onCreate(Bundle savedInstanceState) { System.out.println(a.getName()); //輸出 A Service } }
ServicePool
注入對(duì)象時(shí),會(huì)根據(jù)
Service
配置的生命周期類型
(scope)
和優(yōu)先級(jí)來(lái)決定當(dāng)前是創(chuàng)建還是直接返回緩存對(duì)象。
如果IA有多個(gè)實(shí)現(xiàn),如上圖所示,
ServicePool
會(huì)比較每個(gè)實(shí)現(xiàn)優(yōu)先級(jí),來(lái)決定最
終返回IA的哪個(gè)實(shí)現(xiàn)
@Service
注解標(biāo)記一個(gè)實(shí)現(xiàn)類時(shí)候可以通過(guò)參數(shù)priority指定這個(gè)實(shí)現(xiàn)類的優(yōu)先級(jí)ServicePool
默認(rèn)會(huì)返回優(yōu)先級(jí)最高的實(shí)現(xiàn)類對(duì)象ServicePool
.
getService(AService1.class)
將會(huì)返回一個(gè)
AService1
對(duì)象/** * 服務(wù)池pool中 * * IPriorityService.java */ public interface IPriorityService { int getPriority(); }
/** * 組件A中 * * PriorityService1.java * PriorityService2.java */ @Service(priority = 1) public class PriorityService1 implements IPriorityService { @Override public int getPriority() { return 1; } } @Service(priority = 2) public class PriorityService2 implements IPriorityService { @Override public int getPriority() { return 2; } }
組件B中執(zhí)行: IPriorityService priorityService = ServicePool.getService(IPriorityService.class); System.out.println("priority is " + priorityService.getPriority()); priorityService = ServicePool.getService(PriorityService1.class); System.out.println("priority is " + priorityService.getPriority()); priorityService = ServicePool.getService(PriorityService2.class); System.out.println("priority is " + priorityService.getPriority()); 輸出: priority is 2 priority is 1 priority is 2
典型應(yīng)用場(chǎng)景
Java Library
組件和
Android Library
組件使用不同的服務(wù), 如
classloader
等等。debug
環(huán)境,
release
環(huán)境或者不同的
productFlavor
使用不同的服務(wù), 如
logger
,
Mock
等等每個(gè)由
ServicePool
創(chuàng)建的
service
對(duì)象都有各自生命周期,
service
對(duì)象的生命周期由
ServicePool
管理, 并由
@Service
注解配置生命周期類型。
Service
有
once
,
temp
,
global
三種生命周期類型.Service
的生命周期為
once
,
@Service(scope=IService.Scope.once)
,每次
ServicePool.getService()
都會(huì)創(chuàng)建一個(gè)新的對(duì)象,對(duì)象使用后隨
gc
自動(dòng)被回收,
scope
默認(rèn)為
once
Service
的生命周期為
temp
,
@Service(scope=IService.Scope.temp)
,
Service
由
WeakReference
緩存,只適用無(wú)狀態(tài)服務(wù)。Service
的生命周期為
global
,
@Service(scope=IService.Scope.global)
,每次
ServicePool.getService()
拿到的都是同一個(gè)對(duì)象,
App
運(yùn)行期間不會(huì)被回收組件A中 /** * * OnceService.java */ @Service(scope = IService.Scope.once) public class OnceService implements LifecycleService { } /** * * TempService.java */ @Service(scope = IService.Scope.temp) public class TempService implements LifecycleService { } /** * * GlobalService.java */ @Service(scope = IService.Scope.global) public class GlobalService implements LifecycleService { }
組件B中執(zhí)行: System.out.println(ServicePool.getService(OnceService.class) == ServicePool.getService(OnceService.class));//System.out.println(ServicePool.getService(TempService.class) == ServicePool.getService(TempService.class));//不可靠 System.out.println(ServicePool.getService(GlobalService.class) == ServicePool.getService(GlobalService.class));輸出:falsetrue
/** * 服務(wù)池pool中 * * IPathService.java */ public interface IPathService { String pathServiceName(); }
/** * 組件A中 * * PathService */ @Service(path = "pathService") public class PathService implements IPathService { @Override public String pathServiceName() { return "Path Service"; } }
IPathService
是任意定義的接口,它可以有一個(gè)或多個(gè)實(shí)現(xiàn)類,只要在實(shí)現(xiàn)類上加
@Service
注解并指定
path
屬性。我們就可以通過(guò)
ServicePool.getService(path)
來(lái)找到或者創(chuàng)建他的實(shí)現(xiàn)類對(duì)象。
組件B中執(zhí)行: IPathService pathService = ServicePool.getService("pathService"); System.out.println(pathService.pathServiceName()); 輸出: Path Service
activity
路由path
將橋接方法分發(fā)到對(duì)應(yīng)執(zhí)行器
app
開(kāi)發(fā)過(guò)程中,肯定少不了對(duì)組件進(jìn)行初始化,無(wú)論是內(nèi)部組件還是引用外部庫(kù),很多都需要執(zhí)行初始化操作。常規(guī)的方式是所有初始化操作都是放到
Application
的
onCreate()/onAttachBaseContext()
方法中執(zhí)行。組件有很多而
Application
只有
1
個(gè), 如何讓每個(gè)組件都可以擁有它自己的初始化類呢?
ServciePool
中有一個(gè)
@Init
注解,任何被
@Init
注解標(biāo)記的
Service
類被認(rèn)為是一個(gè)需要執(zhí)行操作初始化操作的
Service
類, 同時(shí)這個(gè)
Service
類需要實(shí)現(xiàn)
IInitService
接口。
@Init(lazy = false) //lazy = false表示禁用懶加載,則該Service會(huì)隨Application初始化而初始化 @Service public class InitService implements IInitService { @Override public void onInit() { //do something. } }
如果初始化組件想要隨
Application
初始化而初始化,需要將
@Init
注解的
lazy
賦值為
false
,表示禁用懶加載。除了
lazy
屬性,
@Init
注解還有
async
,
dependencies
兩個(gè)屬性。
async
屬性顧名思義是異步執(zhí)行,
async
默認(rèn)為
false
,設(shè)置為
true
表示該組件初始化會(huì)在異步線程執(zhí)行。
dependencies
可以傳遞一個(gè)初始化組件類數(shù)組,表示當(dāng)前組件初始化依賴這個(gè)數(shù)組中的所有組件。
ServicePool
會(huì)先初始化數(shù)組中的組件再去執(zhí)行當(dāng)前組件的初始化。
@Init @Service public class InitService1 implements IInitService { @Override public void onInit() { System.out.println("Service 1 Inited!!!"); } } @Init @Service public class InitService2 implements IInitService { @Override public void onInit() { System.out.println("Service 2 Inited!!!"); } } @Init(lazy = false, dependencies=[InitService1.class, InitService2.class]) @Service public class InitService3 implements IInitService { @Override public void onInit() { System.out.println("Service 3 Inited!!!"); } }
ServicePool
的初始化在
https://juejin.im/post/5e1ef261f265da3e0535f10a這篇文章的最后中有實(shí)際應(yīng)用,也可做為示例參考。
所有初始化操作都隨
Application
啟動(dòng)執(zhí)行,一方面會(huì)導(dǎo)致
Application
非常臃腫,另一方面雖然單個(gè)組件初始化時(shí)長(zhǎng)很短,但
n
多個(gè)組件初始化時(shí)長(zhǎng)結(jié)合在了一起就會(huì)導(dǎo)致啟動(dòng)時(shí)間超長(zhǎng)。懶加載是
ServicePool
的核心思想。所有組件只有在第一次被使用時(shí)才會(huì)被創(chuàng)建和執(zhí)行初始化。而不是集中在
Application
初始化過(guò)程。分散初始化從而減輕
App
啟動(dòng)壓力。舉個(gè)????微信分享是很常用的功能,我們以微信分享為例,
WXShareManager
用來(lái)助力微信分享相關(guān)操作。
@Init @Service public class WXShareManager implement IInitService { public static final String appId = "wx499fa9b1ba4a93db"; public static final String userName = "gh_6619a14a139d"; @Override public void onInit() { IWXAPI wxApi = WXAPIFactory.createWXAPI(mContext, null); wxApi.registerApp(appId); } public void share(...) { //do wx share. } }
shareManager
注入對(duì)象的時(shí)候初始化操作會(huì)被執(zhí)行。
public class ShareActivity extends AppcompatActivity { @Service private WXShareManager shareManager;//此時(shí)會(huì)觸發(fā)WXShareManager的onInit初始化。 ... void onClick(View v) { shareManager.share(...); } }
未完待續(xù)....
未完待續(xù)....
star下我的GitHub: https://github.com/Meng997998/AndroidJX,給文章點(diǎn)個(gè)贊一起學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。