組件化開發過程當中,隨着組件愈來愈多,組件的以前的交互就會變得很是的複雜,此時組件間通訊變得尤爲的重要,ServicePool就是爲組件化而生,用最簡單的方式進行組件間通訊。使用依賴注入,按需靈活注入組件。同時支持組件熱插拔,達到組件即插即用的效果。可配置組件生命週期,作到組件按需建立和及時回收,充分利用懶加載的思想,有效解決組件初始化耗時致使的app啓動速度問題。點擊進入 項目地址java
ServicePool包含有 Activity路由, 組件路由等等最經常使用的組件化能力。除此以外,組件化開發過程當中有沒有遇到過想使用某個已有的類,好比一個工具類的時候,發現這個工具類在當前類的上層,沒法直接依賴和引用,而修改這個工具類的層級又會牽一髮而動全身的問題? 有沒有想要一個差別響應的能力,在不一樣的組件中或者環境下,有着不一樣的響應方式?有沒有想要一個自適應場景的能力,自動適應當前環境(好比Java仍是Android環境,好比Debug環境仍是Release環境等等),從而使用最合適的功能。又有沒有想過如何讓組件作到像USB接口同樣插上就能直接使用,拔掉也不影響主體功能的即插即用的效果。等等...。 下面就來具體介紹一下這個組件化神器——ServicePool!git
如上圖所示:github
/**
* 服務池pool中
*
* IA.java
*/
public interface IA {
void aName();
}
/**
* 服務池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中執行: 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中執行: 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 複製代碼
因爲全部示例涉及到依賴注入,這裏提早對ServicePool的依賴注入作個說明。和其餘注入框架不一樣,ServicePool的注入方式很簡單,只有一種注入方式就是直接經過Class注入。數組
@Service public class AImpl implements IA { @Override public String aName() { return "A Impl" } } 複製代碼
ServicePool就是一個基於Class注入容器。最後經過ServicePool.getService(IA.class)方法注入對象, 也能夠經過@Service標記成員變量的方式注入,這兩個方法等價。緩存
public class MainActivity extends AppcompatActivity {
/**
* 等價於
* IA = ServicePool.getService(IA.class);
*/
@Service
private IA a;
@Override
public void onCreate(Bundle savedInstanceState) {
System.out.println(a.getName()); //輸出 A Service
}
}
複製代碼
ServicePool注入對象時,會根據Service配置的生命週期類型(scope)和優先級來決定當前是建立仍是直接返回緩存對象。bash
若是IA有多個實現,如上圖所示,ServicePool會比較每一個實現優先級,來決定最終返回IA的哪一個實現微信
/**
* 服務池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中執行: 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 複製代碼
每一個由ServicePool建立的service對象都有各自生命週期,service對象的生命週期由ServicePool管理, 並由@Service註解配置生命週期類型。markdown
組件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中執行: 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)); 輸出: false true 複製代碼
因爲ServicePool是基於class作的注入操做, ServicePool內部會將path映射成Class,這個映射操做是在編譯期完成的。app
/**
* 服務池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是任意定義的接口,它能夠有一個或多個實現類,只要在實現類上加@Service註解並指定path屬性。咱們就能夠經過ServicePool.getService(path)來找到或者建立他的實現類對象。框架
組件B中執行: IPathService pathService = ServicePool.getService("pathService"); System.out.println(pathService.pathServiceName()); 輸出: Path Service 複製代碼
app開發過程當中,確定少不了對組件進行初始化,不管是內部組件仍是引用外部庫,不少都須要執行初始化操做。常規的方式是全部初始化操做都是放到Application的onCreate()/onAttachBaseContext()方法中執行。組件有不少而Application只有1個, 如何讓每一個組件均可以擁有它本身的初始化類呢?
ServciePool中有一個@Init註解,任何被@Init註解標記的Service類被認爲是一個須要執行操做初始化操做的Service類, 同時這個Service類須要實現IInitService接口。
@Init(lazy = false) //lazy = false表示禁用懶加載,則該Service會隨Application初始化而初始化 @Service public class InitService implements IInitService { @Override public void onInit() { //do something. } } 複製代碼
若是初始化組件想要隨Application初始化而初始化,須要將@Init註解的lazy賦值爲false,表示禁用懶加載。 除了lazy屬性,@Init註解還有async,dependencies兩個屬性。
async屬性顧名思義是異步執行,async默認爲false,設置爲true表示該組件初始化會在異步線程執行。
dependencies能夠傳遞一個初始化組件類數組,表示當前組件初始化依賴這個數組中的全部組件。ServicePool會先初始化數組中的組件再去執行當前組件的初始化。
@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!!!"); } } 複製代碼
因爲InitService1, InitService2之間沒有依賴關係,所以他兩的執行順序不肯定,InitService3同時依賴InitService1和InitService2,所以InitService3必定是最後執行的。
Application初始化後執行結果:
Service 2 Inited!!!
Service 1 Inited!!!
Service 3 Inited!!!
複製代碼
ServicePool的初始化在如何優雅的管理多環境下的Android代碼這篇文章的最後中有實際應用,也可作爲示例參考。
全部初始化操做都隨Application啓動執行,一方面會致使Application很是臃腫,另外一方面雖然單個組件初始化時長很短,但n多個組件初始化時長結合在了一塊兒就會致使啓動時間超長。
懶加載是ServicePool的核心思想。全部組件只有在第一次被使用時纔會被建立和執行初始化。而不是集中在Application初始化過程。分散初始化從而減輕App啓動壓力。舉個🌰
微信分享是很經常使用的功能,咱們以微信分享爲例,WXShareManager用來助力微信分享相關操做。
@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注入對象的時候初始化操做會被執行。
public class ShareActivity extends AppcompatActivity {
@Service
private WXShareManager shareManager;//此時會觸發WXShareManager的onInit初始化。
...
void onClick(View v) {
shareManager.share(...);
}
}
複製代碼
未完待續....
快速接入ServicePool