中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

程序員不可以錯過的Android組件化神器-ServicePool!

發布時間:2020-08-13 14:57:52 來源:ITPUB博客 閱讀:165 作者:yilian 欄目:移動開發

介紹

組件化開發過程中,隨著組件越來越多,組件的之前的交互就會變得非常的復雜,此時組件間通信變得尤其的重要, ServicePool就是為組件化而生,用最簡單的方式進行組件間通信。

使用依賴注入,按需靈活注入組件。同時支持組件熱插拔,達到組件即插即用的效果。可配置組件生命周期,做到組件按需創建和及時回收,充分利用懶加載的思想,有效解決組件初始化耗時導致的 app啟動速度問題。

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

ServicePool基礎能力

程序員不可以錯過的Android組件化神器-ServicePool!

如上圖所示:

  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使用 IBServicePool申請 bService
  6. aService, bServiceServicePool創建和管理
  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

依賴注入(DI)

由于所有示例涉及到依賴注入,這里提前對 ServicePool的依賴注入做個說明。和其他注入框架不同, ServicePool的注入方式很簡單,只有一種注入方式就是直接通過類注入。

  @Service
  public class AImpl implements IA {  @Override
  public String aName() {  return "A Impl"
      }
  }

ServicePool就是一個注入容器。最后通過 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)和優先級來決定當前是創建還是直接返回緩存對象。

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

程序員不可以錯過的Android組件化神器-ServicePool!

如果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 = 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

典型應用場景

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

給服務對象指定生命周期

每個由 ServicePool創建的 service對象都有各自生命周期, service對象的生命周期由 ServicePool管理, 并由 @Service注解配置生命周期類型。

  1. Serviceoncetempglobal三種生命周期類型.
  2. 指定 Service的生命周期為 once, @Service(scope=IService.Scope.once),每次 ServicePool.getService()都會創建一個新的對象,對象使用后隨 gc自動被回收,  scope默認為 once
  3. 指定 Service的生命周期為 temp, @Service(scope=IService.Scope.temp), ServiceWeakReference緩存,只適用無狀態服務。
  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));輸出:falsetrue

支持通過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";
      }
  }

IPathService是任意定義的接口,它可以有一個或多個實現類,只要在實現類上加 @Service注解并指定 path屬性。我們就可以通過 ServicePool.getService(path)來找到或者創建他的實現類對象。

  組件B中執行:
      IPathService pathService = ServicePool.getService("pathService");
      System.out.println(pathService.pathServiceName());
  輸出:
      Path Service
典型應用場景:
  1. activity路由
  2. 混合開發中,可以通過 path將橋接方法分發到對應執行器

組件初始化

app開發過程中,肯定少不了對組件進行初始化,無論是內部組件還是引用外部庫,很多都需要執行初始化操作。常規的方式是所有初始化操作都是放到 ApplicationonCreate()/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注解還有 asyncdependencies兩個屬性。 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!!!");
      }
  }

ServicePool的初始化在
https://juejin.im/post/5e1ef261f265da3e0535f10a這篇文章的最后中有實際應用,也可做為示例參考。

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

所有初始化操作都隨 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(...);
      }
  }

組件熱插拔

未完待續....

Activity路由

未完待續....

star下我的GitHub: https://github.com/Meng997998/AndroidJX,給文章點個贊一起學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

红安县| 新源县| 肇东市| 万荣县| 确山县| 青海省| 鹿泉市| 正宁县| 云龙县| SHOW| 武川县| 循化| 普格县| 池州市| 肇源县| 鸡东县| 邻水| 盐亭县| 龙海市| 汝州市| 南通市| 晴隆县| 抚远县| 济阳县| 新郑市| 林西县| 齐齐哈尔市| 岳池县| 句容市| 醴陵市| 乡宁县| 孙吴县| 通榆县| 白城市| 张家界市| 正阳县| 晋中市| 仙居县| 汨罗市| 乳源| 张家界市|