Android組件化神器 —— ServicePool

組件化開發過程當中,隨着組件愈來愈多,組件的以前的交互就會變得很是的複雜,此時組件間通訊變得尤爲的重要,ServicePool就是爲組件化而生,用最簡單的方式進行組件間通訊。使用依賴注入,按需靈活注入組件。同時支持組件熱插拔,達到組件即插即用的效果。可配置組件生命週期,作到組件按需建立和及時回收,充分利用懶加載的思想,有效解決組件初始化耗時致使的app啓動速度問題。點擊進入 項目地址java

ServicePool包含有 Activity路由, 組件路由等等最經常使用的組件化能力。除此以外,組件化開發過程當中有沒有遇到過想使用某個已有的類,好比一個工具類的時候,發現這個工具類在當前類的上層,沒法直接依賴和引用,而修改這個工具類的層級又會牽一髮而動全身的問題? 有沒有想要一個差別響應的能力,在不一樣的組件中或者環境下,有着不一樣的響應方式?有沒有想要一個自適應場景的能力,自動適應當前環境(好比Java仍是Android環境,好比Debug環境仍是Release環境等等),從而使用最合適的功能。又有沒有想過如何讓組件作到像USB接口同樣插上就能直接使用,拔掉也不影響主體功能的即插即用的效果。等等...。 下面就來具體介紹一下這個組件化神器——ServicePool!git

ServicePool基礎能力

基礎能力示意圖

如上圖所示:github

  1. 組件A,B是兩個互不依賴的組件,A,B不能直接通訊
  2. 組件A,B分別經過AService, BService對外提供服務
  3. 組件A,B的接口協議存放在組件服務池pool, 分別是接口IA, IB
  4. 當組件B須要組件A的服務時,組件B使用IA接口向ServicePool申請, 由ServicePool建立並返回aService給組件B, 此時組件b可使用aService的服務了
  5. 同理, 組件A使用IB向ServicePool申請bService
  6. aService,bService由ServicePool建立和管理
  7. 全部Service對象的優先級生命週期能夠經過@Service註解配置
/**
 * 服務池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 複製代碼

支持經過path查找Service

/**
 * 服務池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";
    }
}
複製代碼
組件B中執行:
    IPathService pathService = ServicePool.getService(IPathService.class);
    System.out.println(pathService.pathServiceName());

輸出:
    Path Service
複製代碼

典型應用場景:

  1. activity路由
  2. 混合開發中,能夠經過path將橋接方法分發到對應執行器

指定Service優先級,按優先級順序返回

組件按優先級順序返回示意圖

若是IA有多個實現,如上圖所示,ServicePool會比較每一個實現優先級,來決定最終返回IA的哪一個實現緩存

  1. @Service註解標記一個實現類時候能夠經過參數priority指定這個實現類的優先級
  2. 優先級值越大優先級越高, ServicePool默認會返回優先級最高的實現類對象
  3. 若是多個實現類優先級相同,那麼返回會有不肯定性
  4. 也能夠直接指定具體使用哪一個實現類,如ServicePool.getService(AService1.class)將會返回一個AService1對象
/**
 * 服務池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 = 1)
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
複製代碼

典型應用場景

  1. Java Library組件和Android Library組件使用不一樣的服務, 如classloader等等。
  2. debug環境,release環境或者不一樣的productFlavor使用不一樣的服務, 如logger, Mock等等
  3. 不一樣的業務場景使用不一樣的服務

給服務對象指定生命週期

每一個由ServicePool建立的service對象都有各自生命週期,service對象的生命週期由ServicePool管理, 並由@Service註解配置生命週期類型。bash

  1. Service有once, temp, global三種生命週期類型.
  2. 指定Service的生命週期爲once,@Service(scope=IService.Scope.once),每次ServicePool.getService()都會建立一個新的對象,對象使用後隨gc自動被回收, scope默認爲once
  3. 指定Service的生命週期爲temp,@Service(scope=IService.Scope.temp),Service由WeakReference緩存,只適用無狀態服務。
  4. 指定Service的生命週期爲global,@Service(scope=IService.Scope.global),每次ServicePool.getService()拿到的都是同一個對象,App運行期間不會被回收
組件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
複製代碼

組件初始化

未完待續....app

組件懶加載機制 & 禁用懶加載

未完待續....ide

Activity路由

未完待續....工具

依賴注入

未完待續....組件化

快速接入ServicePoolui

相關文章
相關標籤/搜索