1. 程式人生 > >終極元件化框架專案方案詳解:一個極具參考的元件化專案

終極元件化框架專案方案詳解:一個極具參考的元件化專案

熱文導讀 | 點選標題閱讀

作者:啊哈啊哈哈

https://juejin.im/user/57a211b47db2a2005a7c7216

前言

本文所講的元件化案例是基於自己開源的元件化框架專案:

https://github.com/HelloChenJinJun/NewFastFrame

其中即時通訊(Chat)模組是單獨的專案:

https://github.com/HelloChenJinJun/TestChat

基本介紹

什麼是元件化?

專案發展到一定階段時,隨著需求的增加以及頻繁地變更,專案會越來越大,程式碼變得越來越臃腫,耦合會越來越多,開發效率也會降低,這個時候我們就需要對舊專案進行重構即模組的拆分,官方的說法就是元件化。

為什麼需要元件化和元件化帶來的好處?

1、現在Android專案中程式碼量達到一定程度,編譯將是一件非常痛苦的事情,一般都需要編譯5到6分鐘。Android Studio 推出 instant run 由於各種缺陷和限制條件(比如採用熱修復tinker)一般情況下是被關閉的。而元件化框架可以使模組單獨編譯除錯,可以有效地減少編譯的時間。

2、通過元件化可以更好的進行並行開發,因為我們可以為每一個模組進行單獨的版本控制,甚至每一個模組的負責人可以選擇自己的設計架構而不影響其他模組的開發,與此同時元件化還可以避免模組之間的交叉依賴,每一個模組的開發人員可以對自己的模組進行獨立測試,獨立編譯和執行,甚至可以實現單獨的部署。從而極大的提高了並行開發效率。

元件化的基本框架

元件框架圖

專案結構圖

框架具體實現

基類庫的封裝

基類庫中主要包括開發常用的一些框架。

1、網路請求(多工下載和上傳,採用 Retrofit+RxJava 框架)

2、圖片載入(策略模式,Glide 與 Picasso 之間可以切換)

3、通訊機制(RxBus)

4、基類 adapter 的封裝(支援 item動畫、多佈局item、下拉和載入更多、item點選事件)

5、基類 RecyclerView 的封裝(支援原生風格的下拉載入,item側滑等)

6、mvp 框架

7、各元件的資料庫實體類

8、通用的工具類

9、自定義view(包括對話方塊,ToolBar佈局,圓形圖片等view的自定義)

10、dagger 的封裝(用於初始化全域性的變數和網路請求等配置)

11、其他等等

元件模式和整合模式切換的實現

music元件 下的 build.gradle 檔案,其他元件類似。

//控制組件模式和整合模式
if (rootProject.ext.isAlone) {    apply plugin: 'com.android.application'
} else {    apply plugin: 'com.android.library' } apply plugin: 'com.neenbedankt.android-apt'

android {    compileSdkVersion rootProject.ext.android.compileSdkVersion    buildToolsVersion rootProject.ext.android.buildToolsVersion    defaultConfig {        if (rootProject.ext.isAlone) {            //元件模式下設定applicationId            applicationId "com.example.cootek.music"        }        minSdkVersion rootProject.ext.android.minSdkVersion        targetSdkVersion rootProject.ext.android.targetSdkVersion        versionCode rootProject.ext.android.versionCode        versionName rootProject.ext.android.versionName        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"        if (!rootProject.ext.isAlone) {            //整合模式下Arouter的配置,用於元件間通訊的實現            javaCompileOptions {                annotationProcessorOptions {                    arguments = [moduleName: project.getName()]                }            }        }    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }    compileOptions {        sourceCompatibility JavaVersion.VERSION_1_7        targetCompatibility JavaVersion.VERSION_1_7    }    sourceSets {        main {            //控制兩種模式下的資源和程式碼配置情況            if (rootProject.ext.isAlone) {                manifest.srcFile 'src/main/module/AndroidManifest.xml'                java.srcDirs = ['src/main/java', 'src/main/module/java']                res.srcDirs = ['src/main/res', 'src/main/module/res']            } else {                manifest.srcFile 'src/main/AndroidManifest.xml'            }        }    } } dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {        exclude group: 'com.android.support', module: 'support-annotations'    })    //依賴基類庫    compile project(':commonlibrary')    //用作顏色選擇器    compile 'com.afollestad.material-dialogs:commons:0.9.1.0'    apt rootProject.ext.dependencies.dagger2_compiler    if (!rootProject.ext.isAlone) {    //整合模式下需要編譯器生成路由通訊的程式碼        apt rootProject.ext.dependencies.arouter_compiler    }    testCompile 'junit:junit:4.12'
}

整合模式

1、首先需要在 config.gradle 檔案中設定 isAlone = false

ext { 
    isAlone = false;//false:作為Lib元件存在,true:作為application存在

2、然後 Sync 下。

3、最後選擇 app 執行即可。

元件模式

1、首先需要在 config.gradle 檔案中設定 isAlone = true

2、然後 Sync 下。

3、最後相應的模組(new、chat、live、music、app)進行執行即可。

第三方開源庫和元件版本號的管理

config.gradle 檔案的配置情況

ext { 
    isAlone = false;//false:作為整合模式存在,true:作為元件模式存在 

    // 各個元件版本號的統一管理 
    android = [ 
            compileSdkVersion: 24, 
            buildToolsVersion: "25.0.2", 
            minSdkVersion    : 16, 
            targetSdkVersion : 22, 
            versionCode      : 1, 
            versionName      : '1.0.0', 
    ] 

    libsVersion = [ 
            // 第三方庫版本號的管理 
            supportLibraryVersion = "25.3.0", 
            retrofitVersion = "2.1.0", 
            glideVersion = "3.7.0", 
            loggerVersion = "1.15", 
            // eventbusVersion = "3.0.0", 
            gsonVersion = "2.8.0", 
            butterknife = "8.8.0", 
            retrofit = "2.3.0", 
            rxjava = "2.1.1", 
            rxjava_android = "2.0.1", 
            rxlifecycle = "2.1.0", 
            rxlifecycle_components = "2.1.0", 
            dagger_compiler = "2.11", 
            dagger = "2.11", 
            greenDao = "3.2.2", 
            arouter_api = "1.2.2", 
            arouter_compiler = "1.1.3", 
            transformations = "2.0.2", 
            rxjava_adapter = "2.3.0", 
            gson_converter = "2.3.0", 
            scalars_converter = "2.3.0", 
            rxpermission = "0.9.4", 
            eventbus="3.0.0", 
            support_v4="25.4.0", 
            okhttp3="3.8.1" 
    ] 

    // 依賴庫管理 
    dependencies = [ 
            appcompatV7               : "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion", 
            design                    : "com.android.support:design:$rootProject.supportLibraryVersion", 
            cardview                  : "com.android.support:cardview-v7:$rootProject.supportLibraryVersion", 
            palette                   : "com.android.support:palette-v7:$rootProject.supportLibraryVersion", 
            recycleview               : "com.android.support:recyclerview-v7:$rootProject.supportLibraryVersion", 
            support_v4                : "com.android.support:support-v4:$rootProject.support_v4", 
            annotations               : "com.android.support:support-annotations:$rootProject.supportLibraryVersion", 
            eventBus                  : "org.greenrobot:eventbus:$rootProject.eventbus", 
            glide                     : "com.github.bumptech.glide:glide:$rootProject.glideVersion", 
            gson                      : "com.google.code.gson:gson:$rootProject.gsonVersion", 
            logger                    : "com.orhanobut:logger:$rootProject.loggerVersion", 
            butterknife               : "com.jakewharton:butterknife:$rootProject.butterknife", 
            butterknife_compiler      : "com.jakewharton:butterknife-compiler:$rootProject.butterknife", 
            retrofit                  : "com.squareup.retrofit2:retrofit:$rootProject.retrofit", 
            okhttp3                   : "com.squareup.okhttp3:okhttp:$rootProject.retrofit", 
            retrofit_adapter_rxjava2  : "com.squareup.retrofit2:adapter-rxjava2:$rootProject.rxjava_adapter", 
            retrofit_converter_gson   : "com.squareup.retrofit2:converter-gson:$rootProject.gson_converter", 
            retrofit_converter_scalars: "com.squareup.retrofit2:converter-scalars:$rootProject.scalars_converter", 
            rxpermission              : "com.tbruyelle.rxpermissions2:rxpermissions:[email protected]", 
            rxjava2                   : "io.reactivex.rxjava2:rxjava:$rootProject.rxjava", 
            rxjava2_android           : "io.reactivex.rxjava2:rxandroid:$rootProject.rxjava_android", 
            rxlifecycle2              : "com.trello.rxlifecycle2:rxlifecycle:$rootProject.rxlifecycle", 
            rxlifecycle2_components   : "com.trello.rxlifecycle2:rxlifecycle-components:$rootProject.rxlifecycle_components", 
            dagger2_compiler          : "com.google.dagger:dagger-compiler:$rootProject.dagger_compiler", 
            dagger2                   : "com.google.dagger:dagger:$rootProject.dagger", 
            greenDao                  : "org.greenrobot:greendao:$rootProject.greenDao", 
            transformations           : "jp.wasabeef:glide-transformations:$rootProject.transformations", 
            //路由通訊 
            arouter_api               : "com.alibaba:arouter-api:$rootProject.arouter_api", 
            arouter_compiler          : "com.alibaba:arouter-compiler:$rootProject.arouter_compiler" 
    ] 
}

元件間通訊實現

元件間通訊的實現是採用阿里開源的 Arouter 路由通訊:

https://github.com/alibaba/ARouter

在App工程中,初始化元件通訊資料:

private List<MainItemBean> getDefaultData() { 
    List<MainItemBean> result = new ArrayList<>(); 
    MainItemBean mainItemBean = new MainItemBean(); 
    mainItemBean.setName("校園"); 
    mainItemBean.setPath("/news/main"); 
    mainItemBean.setResId(R.mipmap.ic_launcher); 
    MainItemBean music=new MainItemBean(); 
    music.setName("音樂"); 
    music.setResId(R.mipmap.ic_launcher); 
    music.setPath("/music/main"); 
    MainItemBean live = new MainItemBean(); 
    live.setName("直播"); 
    live.setResId(R.mipmap.ic_launcher); 
    live.setPath("/live/main"); 
    MainItemBean chat = new MainItemBean(); 
    chat.setName("聊天"); 
    chat.setPath("/chat/splash"); 
    chat.setResId(R.mipmap.ic_launcher); 
    result.add(mainItemBean); 
    result.add(music); 
    result.add(live); 
    result.add(chat); 
    return result; 
}

然後在設定每個 item 的點選事件時,啟動元件介面跳轉。

@Override
public void onItemClick(int position, View view) {    MainItemBean item=mainAdapter.getData(position);    ARouter.getInstance().build(item.getPath()).navigation(); }

每個元件入口介面的設定(比如直播 Live 元件,其它元件類似)

@Route(path = "/live/main") 
public class MainActivity extends BaseActivity<List<CategoryLiveBean>, MainPresenter> implements View.OnClickListener {

元件合併時res資源和AndroidManifest配置的問題

我們通過判斷元件處於哪種模式來動態設定專案res資源和Manifest、以及程式碼的位置。以直播元件為例,其它元件類似。

直播元件框架

相關推薦

終極元件框架專案方案一個參考元件專案

熱文導讀 | 點選標題閱讀作者:啊哈啊哈哈https://juejin.im/user/57a2

終極元件框架專案方案

前言 1.什麼是元件化? 專案發展到一定階段時,隨著需求的增加以及頻繁地變更,專案會越來越大,程式碼變得越來越臃腫,耦合會越來越多,開發效率也會降低,這個時候我們就需要對舊專案進行重構即模組的拆分,官方的說法就是元件化。 2.為什麼需要元件化和元件化帶來的好處? 1、 現在Android專案中程式碼量達到

前端模塊開發解決方案

暴露 可見 返回 異步加載 def 今天 htm 硬盤 業務邏輯 一、模塊化開發方案 前端發展到今天,已經有不少模塊化的方案,比如 CommonJS(常用在服務器端,同步的,如nodejs) AMD(常用在瀏覽器端,異步的,如requirejs)(Asynchronous

15年資深架構師一個大型互聯網公司的微服務轉型實踐

微服務 架構 單片服務 微服務是一個比較大的話題,基於我的過往經歷,本文將以 Netflix 為例,分享一個大型互聯網公司如何從一個 Monolithic 的 APP 成功轉型到微服務。文章主要涉及微服務的產生歷史,應用場景,與單片服務區別,微服務帶來的技術、企業組織結構等方面挑戰,以及如何合

HTML5全部元素一個都不能少

The root element <html> <html> 元素是 HTML 文件的根元素。建議為 <html> 元素指定 lang 屬性,便於螢幕閱讀器識別。 <!DOCTYPE html> <html lang="

安卓專案實戰之強大的網路請求框架okGo使用(六)擴充套件專案okServer,更強大的下載上傳功能,支援斷點和多工管理

OkGo與OkDownload的區別就是,OkGo只是簡單的做一個下載功能,不具備斷點下載,暫停等操作,但是這在很多時候已經能滿足需要了。 而有些app需要有一個下載列表的功能,就像迅雷下載一樣,每個下載任務可以暫停,可以繼續,可以重新下載,可以有下載優先順序,這時候OkDownload就有

安卓專案實戰之強大的網路請求框架okGo使用(五)擴充套件專案okRx,完美結合RxJava

前言 在第一篇講解okGo框架新增依賴支援時,還記得我們額外新增的兩個依賴嗎,一個okRx和一個okServer,這兩個均是基於okGo框架的擴充套件專案,其中okRx可以使請求結合RxJava一起使用,而okServer則提供了強大的下載上傳功能,如斷點支援,多工管理等,本篇我們主要講

安卓專案實戰之強大的網路請求框架okGo使用(四)Cookie的管理

Cookie概念相關 具體來說cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在伺服器端保持狀態的方案。同時我們也看到,由於採用伺服器端保持狀態的方案在客戶端也需要儲存一個標識,所以session機制是需要藉助於cookie機制來達到儲存標識的目的,所謂ses

安卓專案實戰之強大的網路請求框架okGo使用(三)快取的使用

相關實體類必須實現序列化介面 使用快取前,必須讓涉及到快取javaBean物件實現Serializable介面,否者會報NotSerializableException。因為快取的原理是將物件序列化後直接寫入資料庫中,如果不實現Serializable介面,會導致物件無法序列化,進而無法

安卓專案實戰之強大的網路請求框架okGo使用(二)深入理解Callback之自定義JsonCallback

前言 JSON是一種取代XML的資料結構,和xml相比,它更小巧但描述能力卻不差,由於它的小巧所以網路傳輸資料將減少更多流量從而加快了傳輸速度,目前客戶端伺服器返回的資料大多都是基於這種格式的,相應的我們瞭解的關於json的解析工具主要有兩個:Gson(Google官方出的)和fas

安卓專案實戰之強大的網路請求框架okGo使用(一)實現get,post基本網路請求,下載上傳進度監聽以及對Callback自定義的深入理解

1.新增依賴 //必須使用 compile 'com.lzy.net:okgo:3.0.4' //以下三個選擇新增,okrx和okrx2不能同時使用,一般選擇新增最新的rx2支援即可 compile 'com.lzy.net:okrx:1.0.2' compile 'com.lzy

mac下IDEA配置Spring框架+mybatis+maven配置管理的web專案過程

下面詳細講一下mac下怎麼利用IDEA來搭建一個利用spring框架+maven配置管理的web專案 1.再IDEA裡新建一個maven project,填入建立專案所必要的資訊 2.我們要利用spring框架或mybatis就得把與其相關的內容引入進專案啊,利用mav

Scrapy 爬蟲框架入門案例

tin mon setting 爬蟲框架 finished perror project 原因 create 歡迎大家關註騰訊雲技術社區-博客園官方主頁,我們將持續在博客園為大家推薦技術精品文章哦~ 作者:崔慶才 Scrapy入門 本篇會通過介紹一

接口自動化測試方案

system earch ply 找我 發現 safari todo 文件中 timestamp 前言 去年,我們進行了項目的拆分,拆分後的各個子系統也都逐步的改成了通過接口進行數據的交換,接口測試也被提上日程。經過一段時間的探索,接口自動化測試方案越來越完善,今天給大

傳美雲商系統軟件方案

ext mage 系統 做到 function ice 一個 集成 現在 傳美雲商系統是通過頤和果園讓公眾所知道的,頤和果園是做水果生鮮食品市場的,運用傳美雲商這個軟件為什麽能打通互聯網市場?究其主要原因是因新零售正在發生日新月異的變化! 任何新零售都需要數據的支撐。辦公室

22.Linux-塊設備驅動之框架詳細分析()

磁盤設備 回調 隊列 rst 學習 更新 表示 索引 函數實現 1.之前我們學的都是字符設備驅動,先來回憶一下 字符設備驅動: 當我們的應用層讀寫(read()/write())字符設備驅動時,是按字節/字符來讀寫數據的,期間沒有任何緩存區,因為數據量小,不能隨機讀取數據,

企業級代碼上線方案

代碼上線 代碼備份 軟鏈接 中小型企業代碼上線準則 (1)上線說明****對於重要的升級上線來說先有運維人員備份所有重要數據,然後經過開發人員測試和內部測試成功後直接上傳的站點目錄,出現問題後采用歷史代碼回滾策略。而對普通升級來說,先備份必要數據,然後代碼在開發人員和內外網測試成功後可直接上線。(

python調度框架APScheduler使用

body format nbsp start == value latest Coding iso # coding=utf-8 2 """ 3 Demonstrates how to use the background scheduler to schedule

k8s一個完整的監控方案(Heapster+Grafana+InfluxDB) - kubernetes

ear required clust heapster lec beta 成功 use type 1、淺析整個監控流程 heapster以k8s內置的cAdvisor作為數據源收集集群信息,並匯總出有價值的性能數據(Metrics):cpu、內存、網絡流量等,然後將這些數

Struts2框架執行流程

Struts2框架執行流程詳解1. Struts2源碼導入對於struts2框架它的源代碼我們主要使用三部分 struts2核心部分源代碼 org.apache.struts2xxsrc\core\src\main\java struts2的xwork核心部分源代碼src\xwork-core\src\m