您好,登录后才能下订单哦!
组件化开发过程中,随着组件越来越多,组件的之前的交互就会变得非常的复杂,此时组件间通信变得尤其的重要,
ServicePool
就是为组件化而生,用最简单的方式进行组件间通信。
使用依赖注入,按需灵活注入组件。同时支持组件热插拔,达到组件即插即用的效果。可配置组件生命周期,做到组件按需创建和及时回收,充分利用懒加载的思想,有效解决组件初始化耗时导致的
app
启动速度问题。
ServicePool
包含有
Activity
路由, 组件路由等等最常用的组件化能力。除此之外,组件化开发过程中有没有遇到过想使用某个已有的类,比如一个工具类的时候,发现这个工具类在当前类的上层,无法直接依赖和引用,而修改这个工具类的层级又会牵一发而动全身的问题?有没有想要一个差异响应的能力,在不同的组件中或者环境下,有着不同的响应方式?有没有想要一个自适应场景的能力,自动适应当前环境(比如
Java
还是
Android
环境,比如
Debug
环境还是
Release
环境等等),从而使用最合适的功能。又有没有想过如何让组件做到像USB接口一样插上就能直接使用,拔掉也不影响主体功能的即插即用的效果。等等...。下面就来具体介绍一下这个组件化神器——
ServicePool
!
如上图所示:
A
,
B
是两个互不依赖的组件,
A
,
B
不能直接通信A
,
B
分别通过
AService
,
BService
对外提供服务A
,
B
的接口协议存放在组件服务池
pool
, 分别是接口IA, IBServicePool
申请, 由
ServicePool
创建并返回
aService
给组件B, 此时组件
b
可以使用
aService
的服务了A
使用
IB
向
ServicePool
申请
bService
aService
,
bService
由
ServicePool
创建和管理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
由于所有示例涉及到依赖注入,这里提前对
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)
和优先级来决定当前是创建还是直接返回缓存对象。
如果IA有多个实现,如上图所示,
ServicePool
会比较每个实现优先级,来决定最
终返回IA的哪个实现
@Service
注解标记一个实现类时候可以通过参数priority指定这个实现类的优先级ServicePool
默认会返回优先级最高的实现类对象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
典型应用场景
Java Library
组件和
Android Library
组件使用不同的服务, 如
classloader
等等。debug
环境,
release
环境或者不同的
productFlavor
使用不同的服务, 如
logger
,
Mock
等等每个由
ServicePool
创建的
service
对象都有各自生命周期,
service
对象的生命周期由
ServicePool
管理, 并由
@Service
注解配置生命周期类型。
Service
有
once
,
temp
,
global
三种生命周期类型.Service
的生命周期为
once
,
@Service(scope=IService.Scope.once)
,每次
ServicePool.getService()
都会创建一个新的对象,对象使用后随
gc
自动被回收,
scope
默认为
once
Service
的生命周期为
temp
,
@Service(scope=IService.Scope.temp)
,
Service
由
WeakReference
缓存,只适用无状态服务。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
/** * 服务池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
activity
路由path
将桥接方法分发到对应执行器
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!!!"); } }
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(...); } }
未完待续....
未完待续....
star下我的GitHub: https://github.com/Meng997998/AndroidJX,给文章点个赞一起学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。