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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

组件化实践详解(二)

發(fā)布時間:2025/3/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 组件化实践详解(二) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在上一篇文章《組件化實踐詳解(一)》中我們介紹了組件化實踐的目標(biāo)和實踐步驟,本文繼續(xù)說說關(guān)于組件化實踐遇到的問題及思考。

1、組件內(nèi)的架構(gòu)設(shè)計

這條本來我是不想寫的,但是很多組件化的文章里都會費盡心思的寫組件內(nèi)的架構(gòu)設(shè)計。

那我也談一談我的看法:首先回歸初心,想想組件化的目的,為了各個業(yè)務(wù)組件可以單獨運行。劃重點:目的是單獨運行,把之前在App Module的代碼挪到自己單獨的Module,然后能夠獨立運行;而不是大面積重構(gòu)!!我也相信對于大部分團隊,實際上并沒有很多的時間去做重構(gòu),尤其是在做組件化的過程中同時大面積重構(gòu),確定做了風(fēng)險評估嗎

對于組件化的整體設(shè)計,需要遵循制定的規(guī)則,但是對于組件內(nèi)的架構(gòu)設(shè)計,實際上不需要特殊的要求,代碼你愛怎么寫就可以怎么寫,不管你使用MVC、MVP還是MVVM,根據(jù)各自情況合理選擇就好了。這個話題本來就不屬于組件化項目的范疇。

2、調(diào)試方式

假如之前的幾步我們都順利完成,現(xiàn)在整個Project已經(jīng)變成了下圖整個樣子。

那我們的Module要怎么才能跑起來呢?

  • 我們創(chuàng)建Module的時候如果選擇的是Application工程,毋庸置疑肯定是能跑起來的,但是卻沒有辦法被真正的Host宿主引用了
  • 創(chuàng)建Module的時候選擇的是Library工程,可以被引用但是無法自己單獨運行
  • 二者結(jié)合呢?借助馮大大在MDCC上的分享,將Module分為兩個模式:Release模式和Debug模式,Release模式下作為Library,供宿主依賴;而在Debug模式下則作為Application工程,自己單獨運行

    build.gradle中根據(jù)gradle中的一個屬性值來判斷處于哪種模式下:

    if (isDebug.toBoolean()) {apply plugin: 'com.android.application'} else {apply plugin: 'com.android.library'}sourceSets {main {if (isDebug.toBoolean()) {manifest.srcFile 'src/main/debug/AndroidManifest.xml'} else {manifest.srcFile 'src/main/release/AndroidManifest.xml'}}} 復(fù)制代碼

    在Release中的AndroidManifest配置默認(rèn)啟動的主Activity。

    這樣一來調(diào)試的問題也就解決了。但是實際上這僅僅是一個Demo雛形,我們思考幾個帶出來的問題:

  • 如果我這個業(yè)務(wù)組件涉及了別的好幾個Module,也就是我自己使用Debug模式運行的時候別的Module需要使用Release模式,那么每個Module都需要一個單獨的變量去控制,Module過多導(dǎo)致變量過多,出錯可能性陡增
  • 直接的源碼依賴:假如大家在一個分支上開發(fā)不同的組件,有極大可能會導(dǎo)致沖突或者調(diào)用異常導(dǎo)致影響研發(fā)效率;當(dāng)然肯定有人會說一般不會在一個分支開發(fā),確實,但做了組件化之后分支數(shù)其實是可以變少的
  • 如果是Host直接源碼依賴子Module,那當(dāng)子Module作為Application工程運行的時候一旦你Build項目,那各種美如畫的報錯讓你苦不堪言
  • 如何對這個情況做優(yōu)化:各個獨立Module提供穩(wěn)定版本的aar

    • 單獨的業(yè)務(wù)組件開發(fā)完成之后,記錄一個版本號同時提供一個穩(wěn)定的aar
    • 別的依賴模塊直接去compile需要的業(yè)務(wù)組件的aar即可
    • Host宿主則是compile這些業(yè)務(wù)組件穩(wěn)定的aar
    • 依賴于穩(wěn)定的aar,那么自己的業(yè)務(wù)組件開發(fā)并不會影響到別人,而且Build的時候宿主也不會出錯
    • 針對眾多的aar包,最好建一個maven倉庫來統(tǒng)一管理
    • 生成及上傳aar包這步,可以寫個腳本幫忙生成及上傳

    3、工程化經(jīng)驗

    以下介紹些關(guān)于工程化的經(jīng)驗

    3.1 Application

    部分業(yè)務(wù)組件一定會遇到依賴一些三方組件需要提前初始化的情況,正常我們的做法都是在應(yīng)用的Application中做的。此時我們在獨立的Module開發(fā),沒有了應(yīng)用的Application,那么可以自己創(chuàng)建一個Module的Application,以下提幾種實現(xiàn)的思考

  • Module的Application只工作在Debug模式下,而在宿主中也同樣注冊需要的三方組件,Release模式下沒有這個Application則不會重復(fù)注冊
  • Module的Application同時工作于這兩種模式下,但是真正打包生成Apk之后實際系統(tǒng)認(rèn)可的只有App的Application,而別的Module Application只是被系統(tǒng)認(rèn)為是一個沒有特殊意義的普通類。那我們可以在真正的Application方法調(diào)用的時候通過反射調(diào)用Module Application的相應(yīng)方法
  • 源于第二種方案,區(qū)別在于將Module組件中的初始化工作,延遲到組件使用的時候才去初始化,好處就是使用時才加載
  • 備注:而怎么判斷調(diào)用業(yè)務(wù)Module呢?兩個場景:UI跳轉(zhuǎn)或者方法調(diào)用,這兩種判斷可以使用路由框架來協(xié)助。

    3.2 Application與Tinker的兼容

    Tinker作為熱修復(fù)的可靠解決方案,想必很多App都會集成,但是Tinker集成稍繁瑣的地方就在于:為了確保Application也能修復(fù),需要改造Application,改造完成之后打的包出來真正的Application已經(jīng)被修改,而寫上了我們邏輯的Application實際上變成了一個普通類,只是相應(yīng)方法被真正的Application調(diào)用

    那我想把Tinker這個模塊也單獨作為一個Module來使用,能行嗎?首先來思考一個問題:Application要在哪里,Library中還是Host

    答案是Library中,因為各個Module中可能會存在不方便獲取Context的場景,解決方案之一就是使用Application的Context。假設(shè)Application放在Host中,那Module肯定是無法使用的。當(dāng)然剛剛我們說到Module自己的Application,但是別忘了如果Module沒有呢?

    把Application放到Library中也不是說移就能移:

    • 正常情況下我們會發(fā)現(xiàn)Host Application中也有一大堆的邏輯或者是組件初始化,而這些組件要全被移出去還需要 a long long time
    • 代碼中有一大堆通過Host Application拿到的Context,現(xiàn)在忽然移出去,必定一大堆報錯

    面對如此抉擇,那到底是移還是不移?一個好方法是原來Host的Application只做較小改動:并不移出來之前的各種邏輯和組件,而是作為一個普通類,在Library中的Application方法執(zhí)行時去回調(diào)相應(yīng)Host Application的方法;隨后在組件化的過程中逐漸的移出來這些業(yè)務(wù)和組件。這樣的改動成本最小又滿足了當(dāng)下的需要

    3.3 資源沖突

    在拆分出來多個Module或者新建Module進行開發(fā),新建資源的時候可能會有命名的沖突,對Gradle熟悉的同學(xué)可能會表示使用resourcePrefix來進行限定,但是坦白說效果一般,倒是不如在編碼規(guī)范中加上一條以相應(yīng)Module的標(biāo)示作為命名的前綴

    3.4 ButterKnife的使用

    ButterKnife——相信很多同學(xué)都用過,這是一個注解框架,一般在綁定View的時候使用,減少了很多無意義的代碼。在正常開發(fā)中我們用起來也是6的飛起!然而當(dāng)ButterKnife跑在Library工程中的時候各種Build失敗就出現(xiàn)了:原因在于Android Library中的R文件字段并不是常量,Module在Debug模式下是Application工程可以開心玩耍,等真正集成的時候切換回Release模式就呵呵噠了

    在ButterKnife8.0之后也支持了在Library中使用,解決方式就是同時生成了一個R2,這個就是常量,因而可以在Library工程中使用。

    推薦使用Android ButterKnife Plugin Plus插件,方便的一鍵生成然后將R更改為R2;或者自己仿照去寫一個AS插件,直接生成R2

    備注:同時注意R2只能使用在注解中,因而點擊事件要寫成這樣:

    @OnClick(R2.id.tv_back_selerole)public void onClick(View view) {if (view.getId() == R.id.tv_back_selerole) {dealBack();}} 復(fù)制代碼

    3.5 避免過大的基礎(chǔ)庫

    這個問題的引出是在組件化相對成熟的階段,已經(jīng)初步完成了我們的預(yù)期目標(biāo),但是細化的過程中逐漸意識到一個問題:Library庫越來越大,其實單獨的一個Module并不會需要那么多的組件,但是單獨Module運行的時候還是被引用上了,也會拖慢單獨Module的執(zhí)行速度

    于是我們提出了另外一個名詞:去中心化。將基礎(chǔ)庫進行細粒度的拆分,將開發(fā)中一定會用到的例如網(wǎng)絡(luò)請求、EventBus、公共類等放在了Library中,而將別的不常用三方組件如地圖等移出去,只供需要的Module去依賴,而普通的Module則只依賴常用的Library。

    這樣可以有效的避免Library逐漸變得膨脹,也給各Module只去依賴自己需要的特定Library能力

    4、組件化成效

    歷經(jīng)千辛萬苦我們對項目做了組件化實踐,那究竟收獲了哪些好處呢?

    • 代碼結(jié)構(gòu)層次清晰明了;
    • 組件間界限清晰、有明確邊界,低耦合;
    • 開發(fā)過程體驗好,快速編譯;
    • 版本周期內(nèi)沒有動到的組件快速回歸;
    • 方便A/BTest;

    廣告時間

    今日頭條各Android客戶端團隊招人火爆進行中,各個級別和應(yīng)屆實習(xí)生都需要,業(yè)務(wù)增長快、日活高、挑戰(zhàn)大、待遇給力,各位大佬走過路過千萬不要錯過!

    本科以上學(xué)歷、非頻繁跳槽(如兩年兩跳),歡迎加我的微信詳聊:KOBE8242011

    總結(jié)

    以上是生活随笔為你收集整理的组件化实践详解(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。