Android模組化框架介紹

Liberuman發表於2018-09-03

模組化是一種成熟的業務解耦思想,目前已廣泛應用在APP的開發中。之前寫過一篇文章——Android模組化實踐對APP模組化的過程及遇到的問題進行了介紹。具體的例項程式碼最近也完善的差不多了,所以寫篇文章介紹一下這個專案——SimpleProject, 一個以分層思想+模組化開發的通用框架,將會被長期維護。

專案結構

本專案是按照Android模組化實踐中介紹的結構來開展的,所以可先看下這篇文章瞭解一下基本結構。專案結構如下所示:

image

其中,MainModule, BaseComponentDemo, BaseLibraryDemo和CommonBusinessDemo都是業務層模組,他們的關係如圖所示:

image

MainModule是整個APP的主模組,用來實現APP中主頁和路由跳轉相關的邏輯,同時也作為Application與其他模組關聯的樞紐。

BaseComponentDemo, BaseLibraryDemo和CommonBusinessDemo是子業務模組,都依賴於library目錄中的三個公共模組。這三個模組一方面是用來展示業務模組化實現過程,另一方面也是library中三個模組的示例程式碼。所以這三個模組中沒有什麼核心的程式碼,下面主要介紹一下library中的三個模組。

建議

預設情況下,建立的Module都是在Project目錄下,但是當模組比較的多的時候,定位程式碼時還是比較繁瑣的,所以推薦將底層的Module放在建立的library目錄中,然後在setting.gradle中對Module的路徑進行配置:

project(':baselibrary').projectDir = new File('library/baselibrary')
project(':basecomponent').projectDir = new File('library/basecomponent')
project(':commonbusiness').projectDir = new File('library/commonbusiness')
複製程式碼

有時候也會引入一些第三方的Module, 此時也可將其放在library目錄中,或者建立其他的目錄用來存放第三方的Module,然後在setting.gradle中進行配置。這樣Project目錄下只有業務層的Module,專案結構看起來會清晰很多。

baselibrary

baselibrary是Common元件層的實現,包括各種常用的工具類,通用的UI庫,資料來源的封裝(包括網路,檔案,資料庫)。

工具類

commonutils中包含了豐富的工具類,具體介紹如下:

AppUtil: App相關的一些操作,如版本號,程式號,是否已安裝,是否正在執行,是否執行在前臺等;

BitmapUtil: Bitmap相關的一些操作,如縮放,與Drawable之間的轉換等;

CollectionUtil: 與集合/陣列相關的操作;

ConvertUtil: 基本型別與String之間的轉換操作;

DateTimeUtil: 時間格式化相關的操作;

DeviceUtil: 裝置相關的操作,如獲取系統的各種引數;

EncryptUtil: 加密操作,如MD5, 隱藏手機號,郵箱等操作;

FileUtil: 與檔案相關的操作;

InputMethodUtil: 與鍵盤相關的操作,如開啟/隱藏鍵盤,鍵盤彈出時調整EditText位置等;

LaunchUtil: 跳轉到其他APP的操作,如開啟電話,簡訊等;

LogUtil: 日誌工具類;

NetworkUtil: 與網路相關的工具類,如獲取網路引數,獲取聯網狀態等;

PermissionUtil: 許可權驗證類;

RomUtil: 判斷手機ROM的型別;

ScrollStateUtil: 判斷可滑動View是否到達頂部或底部;

SpannableStringUtil: 富文字工具類;

ToastUtil: Toast工具類

VerificationUtil: 驗證工具類,如手機號,郵箱,身份證,是否為中文等;

ViewBgUtil: 動態設定View背景的工具類;

ShadowDrawable: 被View設定陰影的工具類;
複製程式碼

資料來源

Android中常用的資料來源也就四個:SharePreference,檔案,資料庫和網路。

SharePreference

SharePreference是Android提供的一種以key-value結構用來儲存少量資料的方式,本質上也是檔案的儲存方式,但是直接使用時比較繁瑣,為了簡化呼叫過程,專案中提供了它的封裝版——PreferencesManager,支援同步和非同步兩種方式。

檔案

檔案方式就是簡單的檔案讀寫,這裡的檔案快取使用了ACache

資料庫

與檔案一樣,資料庫也算是Android中的低頻資料來源,直接使用GreenDAO即可。

網路

網路是Android開發中主要的資料來源,會被大量使用,所以需要進行簡單的封裝,從而簡化網路請求的過程。網路框架使用了Retrofit。 http目錄中是整個網路框架的封裝,其中提供了公共引數,快取,Cookie,認證四種攔截器。同時提供了Gson資料轉換的相容類,避免異常資料轉換時因型別不匹配而導致的閃退。

網路請求示例程式碼:

HttpManager.getInstance().executeRequest(apiService.getUserInfo(), new ResponseProcessor.RequestListener<UserInfoBean>() {
	@Override
	public void onSuccess(UserInfoBean response) {
		// 請求成功
	}

	@Override
	public void onFailure(int code, String msg) {
		// 請求失敗
	}
});
複製程式碼

通用UI

通用UI是一些自定義View,放在這個位置的自定義View需要有高度的可定製性和與業務無關的特徵。

CircleProgressBar: 圓形進度條;

LevelView: 類似Uber的等級選擇器;

RefreshLayout: 下拉重新整理、上拉載入元件;

ResilienceListView: 下拉可回彈的ListView;

ShapeImageView: 可定義形狀的ImageView;

TabLayout: 類似微信底部的Tab元件;
複製程式碼

basecomponent

basecomponent是基礎業務層的實現,用於統一APP的程式碼結構和UI風格。主要包括Activity&Fragment,Dialog的封裝。

Activity & Fragment

Activity&Fragment作為Android中承載View的元件,它們的風格基本決定了APP的整體風格。其實就目前主流的設計,Activity/Fragment的UI也就幾種狀態:

  • 頁面載入時是否有載入圈;
  • 頁面是否有NavigationBar;

總的來說也就這4種情況的組合。針對這4種情況提供了以下封裝類:

  • BaesActivity 不需要網路請求的Activity;
  • BaesProgressActivity 需要網路請求的Activity(頁面預設顯示載入圈);
  • BaseFragment 不需要網路請求的Fragment;
  • BaseProgressFragment 需要網路請求的Fragment(頁面預設顯示載入圈);

而對於NavigationBar也提供了三種樣式: 白底,透明,半透明,根據需要進行設定即可。

Dialog

Dialog也是Android開發中常用的UI元件,這裡提供了普通對話方塊,單選對話方塊,多選對話方塊,底部對話方塊四種方式,同時對每一種提供了自定義樣式和Material樣式兩種風格,具體可參考Android通用UI元件之Dialog

commonbusiness

commonbusiness是公共元件層的實現。其中包括APP中一些通用的功能,如登入驗證,許可權驗證,第三方登入,分享,支付,推送等功能。

登入驗證

在Android開發中,有一些頁面是需要登入才能檢視的,如果直接使用判斷登入狀態的方式,就是顯得很繁瑣。所謂為了簡化這種驗證過程,專案中提供了基於AOP的方式,開發者中需要驗證登入狀態的方法上面使用@CheckLogin註解即可。具體程式碼參考aspect目錄。

許可權驗證

Android6.0之後許可權的獲取都是通過動態獲取的,但是獲取的過程比較繁瑣,所以為了簡化許可權的獲取過程,這裡也使用了基於AOP的許可權申請。在需要申請許可權時,使用@CheckPermission註解即可,程式碼如下所示:

@CheckPermission(permissions = {Manifest.permission.CAMERA,}, permissionDesc = "沒有許可權無法使用相機", settingDesc = "快去設定中開啟許可權")
private void setUserIcon() {
	
}
複製程式碼

當使用者拒絕了許可權申請後,彈出toast提示permissionDesc中的內容,當勾選了【不再詢問】拒絕後,再次申請就會彈出Dialog, 提示內容為settingDesc,當然,這兩個欄位也是有預設值的,如果不需要詳細的提示,可不用設定。

第三方登入

現在的應用除了內建的登入功能外,為了便於使用者使用,通常還會提供第三方登入的功能。通常使用的第三方登入也就微信,微博,QQ三種。這裡為第三方登入提供了統一的介面,需要登入時直接呼叫即可。

分享

目前APP的主要分享渠道是微信,微博和QQ,所以分享模組也只整合了這三種分享方式。使用時只需要在相應的開發平臺上建立應用並配置引數,然後在分享模組中配置引數即可。當然,專案中也提供了一個分享頁面——ShareActivity,分享時呼叫ShareActivity.enter(...)方法即可。

支付

專案中整合了微信支付和支付寶支付,並且為支付提供了統一了介面,使用時只需要將從後臺獲取的引數傳入即可

支付寶支付
// requestStr是後臺返回的訂單相關的引數
PayManager.getInstance(PayActivity.this).payByAliPay(this, requestStr, new PayManager.AliPayListener() {
	@Override
	public void onSuccess() {
		ToastUtil.show("支付成功");
	}

	@Override
	public void onFailure(Exception e) {
		ToastUtil.show("支付失敗" + e.getMessage());
	}
});
複製程式碼
微信支付
// 根據後臺返回的微信支付的引數構造PayRequestBean物件
PayRequestBean payRequest = new PayRequestBean(...)
PayManager.getInstance(PayActivity.this).payByWeChat(payRequest, new PayManager.AliPayListener() {
	@Override
	public void onSuccess() {
		ToastUtil.show("支付成功");
	}

	@Override
	public void onFailure(Exception e) {
		ToastUtil.show("支付失敗" + e.getMessage());
	}
});
複製程式碼

推送

目前推送的推送率基本都是通過第三方推送SDK組合的方式來保障的,專案中整合了小米,華為,極光推送三種方式,根據機型動態設定推送方式,小米手機使用小米推送,華為推送使用華為推送,其他的品牌則使用極光推送。開發時只需要在Applicataion中呼叫PushManager的init方法進行初始化,並且設定推送的監聽即可。

PushManager.getInstance().initPush(getApplicationContext(), "小米推送的appId",
			"小米推送的appKey");

PushManager.getInstance().setPushListener(new PushListener() {
	@Override
	public void onReceiveMessage(Context context, int pushChannel, Object object) {
		/**
		 * 接收到自定義訊息時的回撥
		 */
	}

	@Override
	public void onReceiveNotification(Context context, int pushChannel, Object object) {
		/**
		 * 接收到通知時的回撥
		 */
	}

	@Override
	public void onNotificationClicked(Context context, int pushChannel, Object object) {
		/**
		 * 點選推送通知時的回撥
		 */
	}
});
複製程式碼

專案地址

SimpleProject

總結

目前的專案已經有個大概的輪廓了,但是細節方面還有許多需要完善的,同時例項程式碼的展示也還不夠詳細,隨後會進一步完善,感興趣的小夥伴可關注一下。

相關文章