日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android组件化开发,组件间的Activity页面跳转。

發布時間:2023/12/16 Android 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android组件化开发,组件间的Activity页面跳转。 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

組件化開發有什么好處?

1、當項目越來越大是,app的業務越來越復雜,會出現業務功能復雜混亂,各功能塊、頁面相互依賴,相互調用太多導致耦合度高,而采用組件化開發,我們就可以將功能模塊合理的劃分,降低功能耦合度。
2、不采用組件化開發時,編譯速度緩慢,修改一個頁面布局編譯一下還得等幾分鐘。使用組件開發后,每次修改只需要編譯對應的模塊即可。
3、有利于團隊協作開發,開發人員之間職責明確,每一個開發人員只需要關注和負責自己的功能點,互不干擾,提高效率。
4、在多渠道或者合作方需求不一致時可以快速拼接功能模塊打包相應的App。

組件化開發項目結構

組件化就是要將項目的各個功能拆成多個模塊,可分為app主模塊,登錄注冊模塊,個人中心模塊,功能模塊等。

組件化架構設計:

1、主工程模塊,主要是APP殼,里面不涉及任何邏輯代碼,只有權限等配置寫在app模塊下的AndroidManifest.xml中。

2、常規業務模塊,該層的組件就是我們真正的業務組件了。我們通常按照功能模塊來劃分業務組件,例如注冊登錄、用戶個人中心、APP的首頁模塊等。這里的每個業務組件都是一個小的APP,只需要修改一下對應的module的build.gradle,就可以單獨編譯,單獨打包成APK在手機上運行。

3、功能組件,一個公共模塊,所有的常規業務模塊都依賴他。字符串、顏色、尺寸資源等寫在該模塊下,該組件是一些通用的工具類。

組件之間必須遵循以下規則:
1、只有上層的組件才能依賴下層組件,不能反向依賴,否則可能會出現循環依賴的情況;
2、同一層之間的組件不能相互依賴,這也是為了組件之間的徹底解耦;

常規業務模塊間的Activity跳轉

由于常規業務模塊之間是不能相互依賴的,所以不能直接使用startActivity進行跳轉。在這里介紹兩種方法:

方法1:
用功能組件(common組件)來統一管理業務組件間的跳轉。

業務組件間不能相互依賴,而A組件需要跳轉到B組件,那么我們可以讓B組件來提供具體的跳轉方法,讓common組件來承擔這個跳轉方法的調用,然后A組件依賴common組件即可,是一個迂回的策略。

其他的組件要跳轉到另外的組件,也是同樣的處理。隨著業務增加可能會有X組件,Y組件等等,那么X組件負責提供跳轉到X組件的方法,Y組件負責提供跳轉到Y組件的方法,并且這些方法,都要經由common組件來管理。

具體代碼實現:

1.各個組件應該提供跳轉到自己的方法,供別的組件調用
具體如何實現呢?對于A組件的跳轉來說,首先,common組件要給別的組件提供一個接口,用于跳轉到A組件。
這個接口寫在common組件里:

/*** 安裝用戶組件對外暴露的接口*/public interface IUserInstallService {// 跳轉到安裝用戶頁面,其中extra是要傳遞的數據void launch(Context context, String extra); }

然后在A組件里,實現此接口(當然A組件的gradle文件得添加對common組件的依賴):

public class UserInstallService implements IUserInstallService {@Overridepublic void launch(Context context, String extra) {Intent intent = new Intent(context, UserInstallActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.putExtra("extra_data", extra); // 傳遞數據context.startActivity(intent);} }

這樣,跳轉方法就已經暴露出來可以供其他組件調用了,那在B組件里,我們怎么調用呢?得想辦法拿到UserInstallService 的實例,然后就能調用它的launch方法來跳轉了。

因為common組件還要管理其它組件的跳轉,所以這些跳轉得統一管理起來:

2.對組件間的跳轉進行統一管理
我們在common組件里寫一個工廠類,用于分配這些跳轉:

public class ServiceFactory {private static ServiceFactory instance;//單例模式private ServiceFactory() {}public static ServiceFactory getInstance() {if (instance == null) {synchronized (ServiceFactory.class) {if (instance == null)instance = new ServiceFactory();}}return instance;}// 安裝用戶組件的跳轉服務的注冊和獲取private IUserInstallService mIUserInstallService;public IUserInstallService getIUserInstallService() {return mIUserInstallService;}public void setIUserInstallService(IUserInstallService mIUserInstallService) {this.mIUserInstallService = mIUserInstallService;} // 其他組件的跳轉服務的注冊和獲取,與A組件的一樣 }

那么很顯然,在B組件里,我們就要想辦法通過common組件的ServiceFactory 的getLoginService()方法來獲取A組件的UserInstallService 的實例。要get,就首先要set,否則拿到的是一個null對象。那么這個set應該放在哪里實現呢?

3.利用Java反射將跳轉服務進行實例化
set UserInstallService 對象的操作肯定得放在跳轉之前,即get之前。最好在B組件初始化的時候就完成set,而且這個set 操作得放在A組件里,要不然又產生依賴了。

有了這個思路,就可以實現如下:
在common組件里,再增加一個接口:

public interface IAppComponent {public void initialize(Application app); }

這個接口用來表示各個組件的初始化。各個組件都要重寫自己的Application,實現這個接口。比如A組件重寫的Application類如下:

public class OrgApp extends Application implements IAppComponent{@Overridepublic void onCreate() {super.onCreate();initialize(this);}@Overridepublic void initialize(Application app) {ServiceFactory.getInstance().setIUserInstallService(new UserInstallService());} }

如果想讓A組件的用于組件單獨運行時,需要在A組件的AndroidManifest.xml里,指定這個類為組件的application:(注:作為module運行時記得刪除android:name=".OrgApp",不然程序會報錯。)

<applicationandroid:name=".OrgApp"android:allowBackup="true"android:label="@string/app_name"android:theme="@style/AppTheme">

但是別忘了,當組件單獨運行時,Application類的onCreate()可以走到;而A組件作為module集成之后,Application類是不會被加載的。

怎么辦呢?因為app殼組件的Application是肯定會被加載的,所以可以在這里,用反射來加載其他組件的Application類。這也是為什么要在common組件里新建IAppComponent 接口類的原因。app殼組件的Application類也要重寫并在manifest里指定。在app殼組件的Application初始化時,可以對其他的組件進行挨個加載,這樣,上面我們想要的set 操作就可以在這里完成了。

為了管理要加載的組件,我們在common組件里新建一個AppConfig類,如下;

public class AppConfig {public static String[] COMPONENTS = {"mod.activity.com.orginfo.application.OrgApp",//這個是A組件的Application類// 還有其他的組件的Application類的全名,也都放這里"mod.activity.com.login.application.LoginApp"}; }

上面這個AppConfig類用來記錄所有的組件的Application類的全名。
下面是app殼組件的新Application類:

public class AppApplication extends Application implements IAppComponent {@Overridepublic void onCreate() {super.onCreate();initialize(this);}@Overridepublic void initialize(Application app) {// 遍歷所有的組件的Application類,依次用反射的方式實例化for (String component : AppConfig.COMPONENTS) {try {Class<?> clazz = Class.forName(component);Object object = clazz.newInstance();// 實例化后,調用各個組件的 set 方法if (object instanceof IAppComponent) {((IAppComponent) object).initialize(app);}} catch (Exception e) {e.printStackTrace();}}} }

經過這樣的處理,上面第二步最后“該在哪里set 跳轉服務”的問題就解決了。總結本篇實現的組件間跳轉原理如下:

在應用啟動的時候,它的APP殼組件的Application類會進行初始化,在這里我們通過反射的方式初始化了其他各組件的Application類,而各組件的Application類在初始化時,又會通過set操作把自己的跳轉服務注冊到common組件。這樣的話,通過common組件get對應的服務,即可實現跳轉。

我們來試一下,在B組件里,跳轉到A組件,就可以這么寫了;

// 安裝用戶 ServiceFactory.getInstance().getIUserInstallService().launch(mContext, "");

這樣B組件就不依賴A組件也可以進行跳轉,實現了我們的期望。

還有一點,要是A組件沒有被集成到app里,那么ServiceFactory.getInstance().getIUserInstallService()就是null,會報空指針異常。我們需要把getIUserInstallService()補充下:

public IUserInstallService getIUserInstallService() {if (mIUserInstallService == null)mIUserInstallService = new EmptyUserInstallService();return mIUserInstallService;}

這里EmptyUserInstallService是對IUserInstallService 接口的一個空實現,目的只是為了避免這個空指針異常,就不貼代碼了。

方法2:
采用路由來實現頁面跳轉,比較成熟的有:

美團的WMRouter:https://tech.meituan.com/meituan_waimai_android_open_source_routing_framework.html

阿里的ARouter:https://github.com/alibaba/ARouter

常規業務模塊間的數據通訊

使用EventBus實現module間的通訊

組件化項目的混淆方案

組件化項目的Java代碼混淆方案采用在集成模式下集中在app殼工程中混淆,各個業務組件不配置混淆文件。集成開發模式下在app殼工程中build.gradle文件的release構建類型中開啟混淆屬性,其他buildTypes配置方案跟普通項目保持一致,Java混淆配置文件也放置在app殼工程中,各個業務組件的混淆配置規則都應該在app殼工程中的混淆配置文件中添加和修改。

之所以不采用在每個業務組件中開啟混淆的方案,是因為 組件在集成模式下都被 Gradle 構建成了 release 類型的arr包,一旦業務組件的代碼被混淆,而這時候代碼中又出現了bug,將很難根據日志找出導致bug的原因;另外每個業務組件中都保留一份混淆配置文件非常不便于修改和管理,這也是不推薦在業務組件的 build.gradle 文件中配置 buildTypes (構建類型)的原因。

注意事項:

1、需要跨module使用的依賴需要用api,而不是implementation,否則common模塊引入庫其他模塊使用不了。
2、其他module想作為APP單獨運行時,需要修改module所在的build.gradle:

application屬性,可以獨立運行的Android程序,也就是我們的APP;

apply plugin: ‘com.android.application’

library屬性,不可以獨立運行,一般是Android程序依賴的庫文件

apply plugin: ‘com.android.library’

未完持續……

參考文章:
1、https://blog.csdn.net/fenggering/article/details/85332523
2、https://www.cnblogs.com/ldq2016/p/9073105.html

總結

以上是生活随笔為你收集整理的Android组件化开发,组件间的Activity页面跳转。的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。