借助Gradle Plugin解決模塊化開發(fā)中模塊如何對外暴露接口

直奔主題,在模塊化開發(fā)中,模塊間的數(shù)據(jù)交流大多數(shù)同學會采用以接口作為通信協(xié)議的方式。需要面對的問題有以下幾點:

  • 接口由誰來維護?
    這個問題簡單,由提供服務的模塊來維護。

  • 接口怎么暴露?
    打成jar包,發(fā)布到maven。

  • 接口在哪里維護?
    現(xiàn)在可以參考的方案有三種:一. 所有相關模塊的接口統(tǒng)一在一個模塊中維護;二. 各個模塊的接口分別在自建一個新的模塊中維護,通過命名規(guī)則一一對應;三. 像微信的.api方案,使用特殊的規(guī)則混雜在各自的模塊中。

如果接著第一個問題,方案一好像就有點難確定接口對應的來源模塊。方案二會出現(xiàn)接口模塊成倍增加,極易出現(xiàn)一個模塊只含一個接口類的現(xiàn)象。方案三需要自定義相關插件,在創(chuàng)建接口時會有點不便,不夠靈活。


MIS登場?。?!接下來先介紹mis的簡單使用以及背后的原理。

MIS

模塊接口服務(Module Interface Service)

MIS是從微信的.api方案演變而來,主要解決的問題是如何在一個模塊內(nèi)維護其對外暴露的接口(包括打包發(fā)布),而不是把接口和接口實現(xiàn)分離到兩個不同的模塊。

mis工程結構

Usage

引用 mis 插件

在根項目的build.gradle中添加mis插件的classpath

buildscript {
    dependencies {
        ...
        classpath 'com.eastwood.tools.plugins:mis:1.3.5'
    }
}

在模塊的build.gradle中添加mis插件

...
apply plugin: 'mis'

創(chuàng)建 mis 目錄

Gradle Sync后,在java同級目錄創(chuàng)建mis文件夾

mis目錄

定義接口,并實現(xiàn)接口服務

直接在mis文件夾下,創(chuàng)建對應的包名、接口類和數(shù)據(jù)Model。并在java文件夾下實現(xiàn)接口服務。

mis接口服務

配置mis相對應的publication

mis {
    publications {
        main {
            groupId 'com.eastwood.demo'
            artifactId 'library-sdk'
            // version '1.0.0-SNAPSHOT'

            dependencies {
                compileOnly 'com.google.code.gson:gson:2.8.1'
            }
        }
    }
    ...
}
  • main指的是src/main/java中的main,除了main之外,其值還可以為 build types和product flavors對應的值,即對應目錄下的mis。比如與src/debug/java對應的src/debug/mis。

  • groupId、artifactIdversion對應的是Maven的GAV。初次配置時不設置version,發(fā)布至maven時設置version

  • dependencies中可聲明該mis編譯和運行時需用到的第三方庫,僅支持compileOnlyimplementation。

發(fā)布至Maven

mis {
    publications {
        main {
            groupId 'com.eastwood.demo'
            artifactId 'library-sdk'
            version '1.0.0-SNAPSHOT'
            ...
        }
    }

    repositories {
        maven {
            url "http://***"
            credentials {
                username '***'
                password '***'
            }
        }
    }
    ...
}
  • 發(fā)布時需設置version。

  • 發(fā)布時內(nèi)部用到的插件是maven-publish,其中repositories相關設置請查閱# Maven Publish Plugin

Gradle Sync后,打開Gradle Tasks View,選擇publishMis[...]PublicationToMavenRepository執(zhí)行發(fā)布任務。

上傳Task

其中publishMis[...]PublicationToMavenLocal 是發(fā)布至本地maven。如果使用本地maven,請將mavenLocal()添加至根項目的build.gradle中,比如:

allprojects {
    repositories {
        google()
        jcenter()
        mavenLocal()
    }
}

Q&A

1.mis目錄下的類會參與編譯嗎?

不會。雖然mis目錄下的類能被java目錄下的類直接引用,但不會參與編譯,真正參與編譯的是該mis目錄生成的jar包,其位于當前工程.gradle/mis下。在當前工程Sync&Build的時候,mis插件會對這些配置了publication的mis目錄進行編譯打包生成jar包,并且依賴該jar包。

mis目錄下的類之所以能被java目錄下的類直接引用,是因為mis目錄被設置為sourceSets aidl的src目錄,而Android Studio對sourceSets aidl的src目錄有特別支持。

2.沒有Maven私服,所有模塊都在一個工程下,其他模塊怎么引用接口?

不設置publicationversion。通過misPublication聲明依賴,比如:

dependencies {
    ...
    implementation misPublication('com.eastwood.demo:library-sdk')
}

misPublication運行機理是會自動在當前工程.gradle/mis下查找是否有對應的mis提供的jar包。如果有,就使用對應的mis提供的jar包;如果沒有且指定了version,就使用maven上的jar包。

3.將接口發(fā)布到maven后,其他模塊通過misPublication聲明依賴,那jar包用的是.gradle/mis下的還是maven上的?

接口被發(fā)布到maven后,其.gradle/mis下的jar包會被刪除,接口所在的模塊根據(jù)publication中設置的GAV使用maven上的jar包。如果其他模塊通過misPublication聲明對其依賴,比如:

dependencies {
    ...
    implementation misPublication('com.eastwood.demo:library-sdk')
    // 或 implementation misPublication('com.eastwood.demo:library-sdk:1.0.0-SNAPSHOT')
}

不管misPublication中是否設置了的version,都會使用maven上的jar包,其版本同接口所在的模塊publication中的GAV。

mis目錄下類發(fā)生實質性的修改后(生成不同的jar包),在當前工程Sync&Build的時,會在.gradle/mis下的重新生成jar包,接口所在的模塊不管publication中是否設置version,都使用.gradle/mis下的jar包。如果其他模塊通過misPublication聲明對其依賴,不管misPublication中是否設置的version,都會使用.gradle/mis下的jar包。

4.為什么在Gradle Tasks View中找不到publishing相關發(fā)布Task?

初次發(fā)布時,請檢查對應的publication是否已經(jīng)設置的version,以及是否添加相關repositories


最后

MIS已經(jīng)上傳至Github,歡迎star交流。QQ 1056453754
https://github.com/EastWoodYang/Mis

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容