原由

成都創(chuàng)新互聯(lián)公司憑借專業(yè)的設計團隊扎實的技術支持、優(yōu)質(zhì)高效的服務意識和豐厚的資源優(yōu)勢,提供專業(yè)的網(wǎng)站策劃、成都網(wǎng)站設計、成都做網(wǎng)站、網(wǎng)站優(yōu)化、軟件開發(fā)、網(wǎng)站改版等服務,在成都十載的網(wǎng)站建設設計經(jīng)驗,為成都近1000家中小型企業(yè)策劃設計了網(wǎng)站。
移動開發(fā)中,隨著項目不斷的跌代,需求越來越復雜后。項目工程也越來越龐大。那么此時的分module的開發(fā),則是必然的選擇了。在最終的組件化之路上,不妨把單一工程比如石器時代,那么接下來簡單的拆分工程分多個moudle開來就是銅器時代。
銅器時代之簡單分module
演進
由于從復雜的單工程拆分了多個module了,達到了代碼及資源的初步的隔離,或需求模塊的開發(fā)人員,開始專注于自己的需求模塊module的開發(fā)了。但是隨著部分需求有相關性,需要相互調(diào)用時。那么問題來了,在AXXX module中
api project(':BXXX')而在BXXX module中
api project(':AXXX')這時出現(xiàn)了相互依賴,首先編譯器會能不過,會出現(xiàn)Circular dependency,循環(huán)相互依賴的問題,這是絕不允許的。
為了解決上述的問題,將AXXX module與BXXX module需要對外提供服務能力支持的,進行封裝與抽象。將需要對外暴露接口/協(xié)議地方,對其抽象出接口出來。把些這接口獨立放在BaseXXXX module中,這樣AXXX module與BXXX module,都分別去
api project(':BaseXXXX')通過BaseXXXX中間module通信去解決AXXX module與BXXX module相互依賴調(diào)用通信。
初步的解決方法
為了在BaseXXXX module中,搭建起AXXX module與BXXX module相互通信的橋梁,可以在BaseXXXX module 定義一個通信標識接口:
/**
*
* 跨module通訊的 標識 interface接口
*/
public interface IModuleApi {
}
然后主要通過ModuleApiHelper進行通信
public class ModuleApiHelper {
private static Map<Class<? extends IModuleApi>,IModuleApi> moduleApiMap = new HashMap<>();
private static Map<Class<? extends IModuleApi>,List<IModuleApi>> moduleApiListMap = new HashMap<>();
/**
* 跨module 注冊進 IKWModuleApi接口,及實現(xiàn)
* 通常可以在 其它的module中 注冊此接口的實現(xiàn),在用的module中getModuleApi拿到接口實現(xiàn)
* 這樣,用的module 不是 必須依賴compile其它module了
* @param clazz
* @param iModuleApi
*/
public static void register(Class<? extends IModuleApi> clazz, IModuleApi iModuleApi){
if (null != iModuleApi && null != clazz){
moduleApiMap.put(clazz, iModuleApi);
}
}
public static void unregister(Class<? extends IModuleApi> clazz){
if (moduleApiMap.containsKey(clazz)){
moduleApiMap.remove(clazz);
}
}
public static void register2List(Class<? extends IModuleApi> clazz, IModuleApi iModuleApi){
if (null != iModuleApi && null != clazz){
if (moduleApiListMap.containsKey(clazz)){
List<IModuleApi> iModuleApis = moduleApiListMap.get(clazz);
iModuleApis.add(iModuleApi);
}else{
List<IModuleApi> iModuleApis = new ArrayList<>();
iModuleApis.add(iModuleApi);
moduleApiListMap.put(clazz, iModuleApis);
}
}
}
public static void unregister2List(Class<? extends IModuleApi> clazz){
if (moduleApiListMap.containsKey(clazz)){
moduleApiListMap.remove(clazz);
}
}
public static void unregisterAll(Class<? extends IModuleApi> clazz){
unregister(clazz);
unregister2List(clazz);
}
public static <T extends IModuleApi> List<T> getModuleListApi(Class<T> clazz){
if (null != clazz){
if (moduleApiListMap.containsKey(clazz)){
List<IModuleApi> iModuleApis = moduleApiListMap.get(clazz);
return (List<T>) iModuleApis;
}else{
return null;
}
}else{
return null;
}
}
/**
* 獲取注冊綁定過來的IKWModuleApi 實現(xiàn)
* @param clazz
* @param <T>
* @return
*/
public static <T extends IModuleApi> T getModuleApi(Class<T> clazz){
if (null != clazz){
if (moduleApiMap.containsKey(clazz)){
return (T) moduleApiMap.get(clazz);
}else{
return null;
}
}else{
return null;
}
}
}
這樣比如在AXXX module中將原有AServiceData類是如下的:
public class AServiceData {
public String getSomeData(){
return "this is some data";
}
public void sayHello(){
System.out.println("hello");
}
}
改造成
public interface IAServiceData extends IModuleApi {
String getSomeData();
void sayHello();
}
public class AServiceData implements IAServiceData{
@Override
public String getSomeData(){
return "this is some data";
}
@Override
public void sayHello(){
System.out.println("hello");
}
}
將IAServiceData接口定義在BaseXXXX module 中。然后AXXX module中進行register相應的服務
public class AModuleService {
public void init(){
ModuleApiHelper.register(IAServiceData.class,new AServiceData());
}
}
這樣調(diào)用AModuleService的init方法,即可對IAServiceData服務進行注冊了。然后即下來,在BXXX module中進行getXXX得到服務即可調(diào)用相應的方法了.
在任何需要此服務的方法可如下調(diào)用:
IAServiceData iaServiceData = ModuleApiHelper.getModuleApi(IAServiceData.class);
注意
1> register注冊時機,需要越早越好,一般建議在各module的有類似的application的onCreate時注冊最好。
2> IModuleApi與ModuleApiHelper,和各extends繼承IModuleApi接口的接口,需要放在中間通信BaseXXX Module中。各需要通信的module去 compile/api BaseXXX Module即可。
問題
為了保證IModuleApi接口注冊有效,需要越早越好進行注冊。這樣隨著項目越來越復雜,需要通信的地方越來越多。統(tǒng)一的ModuleApiHelper,注冊的地方將越來越多帶的問題也多起來。
1> 注冊Map容器占用的內(nèi)存不斷的增多。
2> register注冊的地方不統(tǒng)一,有些放在各module的類Application的onCreate中,有些可能是放在其它的類中.
3> 不支持ui頁面的跳轉(zhuǎn),由AXXX module的AxxActtivy頁面跳轉(zhuǎn)到BXXX module的BxxActivity頁面中。
4> 不支持多進程中應用。
為了解決上述問題,引入了蒸汽時代之ARoute到來。
蒸汽時代之ARoute
由于遍幅的原因,總體概述不詳細細述ARoute,下遍再剖析ARoute。總體來說在多module通信中解決了:
1> 解決了ui頁面的跳轉(zhuǎn)問題。
2> 根據(jù)需要進行register的問題,且register通過靜態(tài)注解來的,所以register地方統(tǒng)一比如容易維護。
但是依然不能解決多進程中的應用。
電器時代之Andromeda
Andromeda解決了多進程,跨進程ipc之間的通信過程,同樣也支持單進程的通信...
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。。
分享題目:androidmodule解耦組件化總體概述(推薦)
當前路徑:http://chinadenli.net/article2/jigpoc.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設計、網(wǎng)站內(nèi)鏈、建站公司、網(wǎng)站維護、虛擬主機、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)