日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

剖析Android項(xiàng)目組件化重構(gòu)架構(gòu)

jf_78858299 ? 來(lái)源:小余的自習(xí)室 ? 作者:小余的自習(xí)室 ? 2023-03-30 10:41 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1.組件化重構(gòu)效果

這里先看下我們重構(gòu)前后的框架圖比較:

重構(gòu)前:

圖片

傳統(tǒng)代碼架構(gòu).png

重構(gòu)后

圖片

組件化代碼架構(gòu).png

  • ft_xxx表示業(yè)務(wù)層模塊 lib_xxx表示基礎(chǔ)庫(kù)模塊

重構(gòu)后的架構(gòu)圖如下

圖片

服務(wù)接口調(diào)用.png

重構(gòu)前的代碼業(yè)務(wù)封裝在宿主app中,業(yè)務(wù)耦合嚴(yán)重,如果修改一個(gè)業(yè)務(wù)模塊,需要對(duì)整個(gè)app進(jìn)行完整測(cè)試,測(cè)試工作量巨大

重構(gòu)后,我們只需要對(duì)單一app進(jìn)行獨(dú)立調(diào)試即可。

重構(gòu)后的框架結(jié)構(gòu):所有的業(yè)務(wù)組件之間通訊都通過(guò)ft_base_service進(jìn)行通訊

2.組件化重構(gòu)準(zhǔn)則

  • 1.單一業(yè)務(wù)可以單獨(dú)調(diào)試,也可以作為lib提供給宿主app使用
  • 2.同一級(jí)別的模塊不允許直接調(diào)用,比如我們的ft_home組件不允許直接調(diào)用ft_login組件,不然組件化的意義就不存在了
  • 3.組件間通訊不能直接使用顯示的class文件跳轉(zhuǎn),可以考慮很用ARouter框架進(jìn)行解耦
  • 4.每個(gè)組件可打包為aar或者jar上傳到maven私服,宿主使用的時(shí)候,直接引用私服中aar包即可

能做到以上幾點(diǎn),你的app就可以稱(chēng)為一個(gè)組件化框架的app了。

3.組件化重構(gòu)思路

圖片

重構(gòu)思路.png

    1. :拆代碼,拆資源,拆構(gòu)建

      由于所有業(yè)務(wù)和資源都耦合在宿主app中,所以需要將代碼和資源拆開(kāi)到對(duì)應(yīng)模塊中

      當(dāng)然我們的構(gòu)建build.gradle也需要拆分到不同模塊中

    1. :對(duì)外提供接口

      組件化之間不能直接通訊,需要使用暴露接口的方式對(duì)外通訊

    1. 測(cè) :反復(fù)測(cè)試

      重構(gòu)后代碼,需要反復(fù)測(cè)試,防止出現(xiàn)意想不到的bug

4.組件化重構(gòu)過(guò)程

這里我以登錄業(yè)務(wù)ft_login為例子:

1. 步驟1 :首先新建一個(gè)業(yè)務(wù)模塊ft_login,然后在宿主app中將登錄功能相關(guān)聯(lián)的代碼和資源抽離到ft_login

2. 步驟2 :將和登錄構(gòu)建相關(guān)的依賴(lài)分配到ft_login構(gòu)建中。

3. 步驟3 :?jiǎn)为?dú)調(diào)試功能實(shí)現(xiàn)

  • 3.1:在gradle.properties中創(chuàng)建一個(gè)全局變量:isRunAlone=true
  • 3.2:在build.gradle中:
if(isRunAlone.toBoolean()){
    apply plugin:'com.android.application'
}else{
    apply plugin:'com.android.library'
}

android {
    compileSdkVersion 33
    buildToolsVersion "33.0.0"

    defaultConfig {
        if(isRunAlone.toBoolean()){
            applicationId 'com.anna.ft_login'
        }
        ...
    }
    sourceSets {
        main {
            java {
                srcDirs = ['src/main/java']
            }
            resources {
                srcDirs = ['src/main/res']
            }
            aidl {
                srcDirs = ['src/main/aidl']
            }
            manifest {
                if(isRunAlone.toBoolean()){
                    srcFile 'src/main/manifest/AndroidManifest.xml'
                }else {
                    srcFile 'src/main/AndroidManifest.xml'
                }
            }
        }
    }
}
def dependList = [rootProject.depsLibs.okhttp,
                  rootProject.depsLibs.gson,
                  rootProject.depsLibs.appcompact,
                  rootProject.depsLibs.design,
                  rootProject.depsLibs.eventbus,
                  rootProject.depsLibs.arouterapi,
                  ':lib_network',':lib_common_ui',':ft_base_service']


dependencies {
    if(!isRunAlone.toBoolean()){
        dependList.each { String depend ->
            depend.startsWithAny(':lib',':ft')? compileOnly(project(depend)):compileOnly(depend){
                switch (depend){
                    case rootProject.depsLibs.arouterapi:
                        exclude group: 'com.android.support'
                        break;
                }
            }
        }
    }else {
        dependList.each { String depend ->
            depend.startsWithAny(':lib',':ft')? implementation(project(depend)):implementation(depend) {
                switch (depend) {
                    case rootProject.depsLibs.arouterapi:
                        exclude group: 'com.android.support'
                        break;
                }
            }
        }
    }
    //arouter注解處理器
    annotationProcessor rootProject.depsLibs.aroutercompiler

    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

}

單獨(dú)調(diào)試狀態(tài)下注意四點(diǎn)

  • 1.引用application插件
  • 2.引入applicationId
  • 3.引入不同給的sourceSets構(gòu)建路徑
  • 4.引入的庫(kù)單獨(dú)調(diào)試狀態(tài)下需要使用implementation導(dǎo)入,不能使用compileOnly

實(shí)現(xiàn)上面四點(diǎn), 只要打開(kāi)isRunAlone就可作為一個(gè)單獨(dú)app運(yùn)行了 。

4.步驟4:組件間通訊

這里,我們引入一個(gè)ft_base_service模塊,這個(gè)模塊用來(lái)實(shí)現(xiàn)組件間通訊用,需要調(diào)用別的業(yè)務(wù)模塊都需要使用這個(gè)模塊才能通訊、

業(yè)務(wù)模塊與ft_base_service之間通訊使用的是路由ARouter

關(guān)于ARouter的使用可以參考這篇文章:

Android開(kāi)源系列-組件化框架Arouter-(一)使用方式詳解

  • 1.創(chuàng)建ft_base_service,在這個(gè)模塊中:創(chuàng)建一個(gè)LoginService接口繼承IProvider

引入ARouter依賴(lài)

android {
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"]
        }
    }
}
//arouter核心api
implementation rootProject.depsLibs.arouterapi
//arouter注解處理器
annotationProcessor rootProject.depsLibs.aroutercompiler

創(chuàng)建LoginService:

public interface LoginService extends IProvider {
    boolean hasLogin();
    void login(Context context);
}
  • 2.在ft_login業(yè)務(wù)模塊中實(shí)現(xiàn)LoginService接口

注意這里因?yàn)槭褂昧薃Router注解,所以也需要引入ARouter依賴(lài)

@Route(path = "/login/login_service")
public class LoginServiceImpl implements LoginService {
    Context context;
    @Override
    public boolean hasLogin() {
        return UserManager.getInstance().hasLogined();
    }

    @Override
    public void login(Context context) {
        LoginActivity.start(context);
    }

    @Override
    public void init(Context context) {
        Log.d("TAG","LoginServiceImpl is init");
    }
}
  • 3.在ft_base_service模塊中對(duì)LoginService接口進(jìn)行依賴(lài)注入
public class LoginImpl {

    @Autowired(name = "/login/login_service")
    public LoginService mLoginService;
    private static LoginImpl mLoginImpl = null;
    public static LoginImpl getInstance() {
        if (mLoginImpl == null) {
            synchronized (LoginImpl.class) {
                if (mLoginImpl == null) {
                    mLoginImpl = new LoginImpl();
                }
                return mLoginImpl;
            }
        }
        return mLoginImpl;
    }

    private LoginImpl(){
        ARouter.getInstance().inject(this);
    }
    public boolean hasLogin(){
        return mLoginService.hasLogin();
    }
    public void login(Context context){
        mLoginService.login(context);
    }

}

筆者使用了一個(gè) 單例類(lèi)LoginImpl ,在構(gòu)造器中對(duì)LoginService依賴(lài)注入

ARouter.getInstance().inject(this);

然后宿主app或者其他模塊引用登錄業(yè)務(wù)功能時(shí),需要依賴(lài)ft_base_service模塊,并使用LoginImpl的接口即可。

這里要說(shuō)明下,平時(shí)我們使用的四大組件跳轉(zhuǎn)也可以使用這個(gè)方式來(lái)處理,在服務(wù)接口中定義跳轉(zhuǎn)接口即可。當(dāng)然也可以使用Arouter的Activity跳轉(zhuǎn)方式或者Fragment實(shí)例獲取方式

  • 5.代碼打包aar上傳到maven私服

關(guān)于這塊maven私服更多內(nèi)容可以參考這篇文章:

Gradle筑基篇(六)-使用Maven實(shí)現(xiàn)組件化類(lèi)庫(kù)發(fā)布

這里我們封裝了一個(gè)通用組件發(fā)布庫(kù):

apply plugin: 'maven'


uploadArchives {
    repositories {
        mavenDeployer {
            // 是否快照版本
            def isSnapShot = Boolean.valueOf(MAVEN_IS_SNAPSHOT)
            def versionName = MAVEN_VERSION
            if (isSnapShot) {
                versionName += "-SNAPSHOT"
            }
            // 組件信息
            pom.groupId = MAVEN_GROUP_ID
            pom.artifactId = MAVEN_ARTIFACTID
            pom.version = versionName

            // 快照倉(cāng)庫(kù)路徑
            snapshotRepository(url: uri(MAVEN_SNAPSHOT_URL)) {
                authentication(userName: MAVEN_USERNAME, password: MAVEN_USERNAME)
            }
            // 發(fā)布倉(cāng)庫(kù)路徑
            repository(url: uri(MAVEN_RELEASE_URL)) {
                authentication(userName: MAVEN_USERNAME, password: MAVEN_USERNAME)
            }

            println("###################################"
                    + "\\nuploadArchives = " + pom.groupId + ":" + pom.artifactId + ":" + pom.version + "." + pom.packaging
                    + "\\nrepository =" + (isSnapShot ? MAVEN_SNAPSHOT_URL : MAVEN_RELEASE_URL)
                    + "\\n###################################"
            )
        }
    }
}

然后在對(duì)應(yīng)的組件下面引用:

apply from:file('../maven.gradle')

發(fā)布的時(shí)候直接在Gradle面板中點(diǎn)擊uploadArchives任務(wù)即可

圖片

task面板.png

經(jīng)過(guò)上面幾個(gè)步驟就基本完成了login組件的封裝并發(fā)布,且對(duì)外提供了login組件接口 其他組件也是按照上面的邏輯進(jìn)行重構(gòu)

更多詳細(xì)信息可以自己拿到項(xiàng)目源代碼查看。

5.組件化重構(gòu)總結(jié)

組件化不僅是一種架構(gòu),更是一種思想,架構(gòu)是可以變得,但是核心思想?yún)s是統(tǒng)一的,在拆分代碼的時(shí)候,要注意模塊的顆粒度,不是顆粒度越小就越好,模塊分離的好,后期對(duì)組件改造會(huì)有很大幫助, 關(guān)于組件化的文章就講到這里,組件化重構(gòu)的項(xiàng)目已經(jīng)上傳到Github。后面會(huì)出一期插件化的項(xiàng)目改造。敬請(qǐng)期待。

** demo地址: https://github.com/ByteYuhb/anna_music_app **

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Android
    +關(guān)注

    關(guān)注

    12

    文章

    4035

    瀏覽量

    134550
  • APP
    APP
    +關(guān)注

    關(guān)注

    33

    文章

    1594

    瀏覽量

    76144
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4977

    瀏覽量

    74417
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Android的系統(tǒng)架構(gòu)包括哪些部分?

    什么是Android以后,再來(lái)說(shuō)說(shuō)Android的系統(tǒng)架構(gòu)包括哪些部分。Android的系統(tǒng)架構(gòu)和其操作系統(tǒng)一樣,采用了分層的
    發(fā)表于 12-04 14:11

    【懸賞100塊】如何實(shí)現(xiàn)FPGA可重構(gòu)計(jì)算(Android平臺(tái))

    LZ我是大四計(jì)算機(jī)的,沒(méi)錯(cuò),我在做畢設(shè),而且?guī)缀跻换I莫展。題目是在Android平臺(tái)上實(shí)現(xiàn)可重構(gòu)計(jì)算:簡(jiǎn)單說(shuō),就是實(shí)現(xiàn)應(yīng)用程序把一部分計(jì)算密集型的任務(wù)交給FPGA來(lái)計(jì)算,把FPGA作為CPU的一個(gè)
    發(fā)表于 05-20 20:03

    STM32庫(kù)函數(shù)架構(gòu)剖析

    STM32庫(kù)函數(shù)架構(gòu)剖析
    發(fā)表于 06-20 17:08

    [資料分享]+Android內(nèi)核剖析

    `[資料分享]+Android內(nèi)核剖析一、看威武霸氣的封面作者:柯元旦 二、讀讀簡(jiǎn)介,看看適合你嗎? 本書(shū)詳細(xì)分析了Android內(nèi)核的內(nèi)部機(jī)制,包括窗口管理系統(tǒng)、Activity管理系統(tǒng)
    發(fā)表于 09-26 10:46

    Android手機(jī)操控ARM開(kāi)發(fā)板外圍硬件設(shè)備【創(chuàng)科之龍】原創(chuàng)

    _源碼架構(gòu)分布剖析零死角玩轉(zhuǎn)Android下_如何進(jìn)行Android源碼編譯Makefile剖析 零死角玩轉(zhuǎn)
    發(fā)表于 01-12 22:31

    Android RIL架構(gòu)簡(jiǎn)介

    架構(gòu)說(shuō)起—Android架構(gòu)從手機(jī)的架構(gòu)說(shuō)起—Android給客戶(hù)的價(jià)值從RIL的架構(gòu)說(shuō)起—R
    發(fā)表于 09-25 15:46

    Android系統(tǒng)的CPU架構(gòu)

    Android CPU 架構(gòu)詳解
    發(fā)表于 04-15 12:00

    初探Android系統(tǒng)整體架構(gòu)

    Android系統(tǒng)龐大且錯(cuò)綜復(fù)雜,今天小編將帶領(lǐng)大家初探Android系統(tǒng)整體架構(gòu),一窺其全貌。引言本文作為Android系統(tǒng)架構(gòu)的開(kāi)篇,起
    發(fā)表于 08-20 06:32

    XML在可重構(gòu)制造執(zhí)行系統(tǒng)組件管理中的應(yīng)用

    基于組件技術(shù)研究和開(kāi)發(fā)可重構(gòu)制造執(zhí)行系統(tǒng)(RMES),需要解決大量不同功能業(yè)務(wù)組件的維護(hù)問(wèn)題。本文基于XML-Schema 機(jī)制設(shè)計(jì)了一套標(biāo)準(zhǔn)描述方法,來(lái)定義RMES
    發(fā)表于 08-24 11:31 ?7次下載

    深入剖析Android消息機(jī)制

    深入剖析Android消息機(jī)制
    發(fā)表于 01-22 21:11 ?11次下載

    關(guān)于iOS組件的分析

    1.組件的目的是什么? 最近一兩年很多人都想在項(xiàng)目里面搞組件,覺(jué)得搞組件
    發(fā)表于 09-25 10:28 ?0次下載
    關(guān)于iOS<b class='flag-5'>組件</b><b class='flag-5'>化</b>的分析

    華為BBF CloudCO架構(gòu)標(biāo)準(zhǔn)為運(yùn)營(yíng)商重構(gòu)寬帶網(wǎng)絡(luò)架構(gòu)提供了關(guān)鍵的參考

    BBF CloudCO架構(gòu)標(biāo)準(zhǔn)為運(yùn)營(yíng)商重構(gòu)寬帶網(wǎng)絡(luò)架構(gòu)提供了關(guān)鍵的標(biāo)準(zhǔn)參考,是邁向云網(wǎng)絡(luò)的關(guān)鍵一步。
    發(fā)表于 10-25 09:45 ?3347次閱讀

    重構(gòu)架構(gòu)技術(shù)的快速發(fā)展,未來(lái)將應(yīng)用于太空

    如今,技術(shù)的進(jìn)步使得低軌飛行越來(lái)越容易商用。賽靈思太空產(chǎn)品系統(tǒng)架構(gòu)師Minal Sawant表示,航天行業(yè)的主要挑戰(zhàn)之一是用于各種項(xiàng)目的體系結(jié)構(gòu),多任務(wù)的靈活架構(gòu)平臺(tái)是如今的一個(gè)挑戰(zhàn)
    發(fā)表于 05-22 10:35 ?975次閱讀

    基于AndroidCrop進(jìn)行鴻蒙的開(kāi)源圖片裁剪組件

    項(xiàng)目是基于開(kāi)源項(xiàng)目 AndroidCrop 進(jìn)行鴻蒙的移植和開(kāi)發(fā)的,可以通過(guò)項(xiàng)目標(biāo)簽以及github地址( https://github
    發(fā)表于 03-23 09:53 ?2次下載

    HarmonyOS實(shí)戰(zhàn):組件項(xiàng)目搭建

    前言 鴻蒙應(yīng)用開(kāi)發(fā)已經(jīng)成為互聯(lián)網(wǎng)新的風(fēng)口,開(kāi)發(fā)鴻蒙軟件已經(jīng)成為今年工作的核心目標(biāo)。在軟件開(kāi)發(fā)過(guò)程中,對(duì)于復(fù)雜度較大,功能較多的軟件都會(huì)采用組件項(xiàng)目架構(gòu),那么對(duì)于鴻蒙應(yīng)用開(kāi)發(fā)是否也能實(shí)
    的頭像 發(fā)表于 06-09 14:58 ?813次閱讀
    HarmonyOS實(shí)戰(zhàn):<b class='flag-5'>組件</b><b class='flag-5'>化</b><b class='flag-5'>項(xiàng)目</b>搭建
    甘泉县| 营山县| 东阿县| 灵宝市| 沽源县| 天等县| 山东| 东乌珠穆沁旗| 鄂温| 都江堰市| 慈利县| 灌南县| 阿勒泰市| 石河子市| 马龙县| 汉川市| 顺义区| 舟山市| 蕉岭县| 卓资县| 伊吾县| 湘阴县| 西充县| 枣阳市| 德清县| 兴化市| 泰兴市| 南和县| 永靖县| 彭山县| 江西省| 思南县| 磴口县| 南安市| 黔西县| 游戏| 平山县| 固阳县| 原平市| 庄河市| 绥德县|