最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

ProtoBuf動(dòng)態(tài)拆分Gradle?Module解析

 更新時(shí)間:2023年02月27日 14:04:28   作者:究極逮蝦戶  
這篇文章主要為大家介紹了ProtoBuf動(dòng)態(tài)拆分Gradle?Module解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

預(yù)期

當(dāng)前安卓的所有proto都生成在一個(gè)module中,但是其實(shí)業(yè)務(wù)同學(xué)需要的并不是一個(gè)大雜燴, 只需要其中他們所關(guān)心的proto生成的類則足以。所以我們希望能將這樣一個(gè)大雜燴的倉(cāng)庫(kù)打散,拆解成多個(gè)module。

buf.yaml

Protobuf是Protocol Buffers的簡(jiǎn)稱,它是Google公司開(kāi)發(fā)的一種數(shù)據(jù)描述語(yǔ)言,用于描述一種輕便高效的結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)格式,并于2008年對(duì)外開(kāi)源。Protobuf可以用于結(jié)構(gòu)化數(shù)據(jù)串行化,或者說(shuō)序列化。它的設(shè)計(jì)非常適用于在網(wǎng)絡(luò)通訊中的數(shù)據(jù)載體,很適合做數(shù)據(jù)存儲(chǔ)或 RPC 數(shù)據(jù)交換格式,它序列化出來(lái)的數(shù)據(jù)量少再加上以 K-V 的方式來(lái)存儲(chǔ)數(shù)據(jù),對(duì)消息的版本兼容性非常強(qiáng),可用于通訊協(xié)議、數(shù)據(jù)存儲(chǔ)等領(lǐng)域的語(yǔ)言無(wú)關(guān)、平臺(tái)無(wú)關(guān)、可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)格式。開(kāi)發(fā)者可以通過(guò)Protobuf附帶的工具生成代碼并實(shí)現(xiàn)將結(jié)構(gòu)化數(shù)據(jù)序列化的功能。

在我司proto相關(guān)的都是由后端大佬們來(lái)維護(hù)的,然后這個(gè)協(xié)議倉(cāng)庫(kù)會(huì)被android/ios/后端/前端 依賴之后生成對(duì)應(yīng)的代碼,然后直接使用。

而proto文件中允許導(dǎo)入對(duì)于其他proto文件的依賴,所以這就導(dǎo)致了想要把幾個(gè)proto轉(zhuǎn)化成一個(gè)java-library工程,還需要考慮依賴問(wèn)題。所以由 我們的后端來(lái)定義了一個(gè)buf.yaml的數(shù)據(jù)格式。

version: v1
name: buf.xxx.co/xxx/xxxxxx
deps:
  - buf.xxxxx.co/google/protobuf
build:
  excludes:
    - setting
breaking:
  use:
    - FILE
lint:
  use:
    - DEFAULT

name代表了這個(gè)工程的名字,deps則表示了他依賴的proto的工程名?;谶@份yaml內(nèi)容,我們就可以大概確定一個(gè)proto工程編譯需要的基礎(chǔ)條件。然后我們只需要一個(gè)工具或者插件來(lái)幫助我們生成對(duì)應(yīng)的工程就夠了。

模板工程

現(xiàn)在我們基本已經(jīng)有了一個(gè)單一的proto工程的輸入模型了,工程名依賴的工程還有對(duì)應(yīng)文件夾下的proto文件。然后我們就可以基于這部分輸入的模型,生成出第一個(gè)模板工程。

plugins {
    id 'java-library'
    id 'org.jetbrains.kotlin.jvm'
    id 'com.google.protobuf'
}


java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

sourceSets {
    def dirs = new ArrayList<String>()
    dirs.add("src/main/proto")
    main.proto.srcDirs = dirs
}

protobuf {
    protoc {
        if (System.getProperty("os.arch").compareTo("aarch64") == 0) {
            artifact = "com.google.protobuf:protoc:$version_protobuf_protoc:osx-x86_64"
        } else {
            artifact = "com.google.protobuf:protoc:$version_protobuf_protoc"
        }
    }
    plugins {
        grpc {
            if (System.getProperty("os.arch").compareTo("aarch64") == 0) {
                artifact = 'io.grpc:protoc-gen-grpc-java:1.36.1:osx-x86_64'
            } else {
                artifact = 'io.grpc:protoc-gen-grpc-java:1.36.1'
            }
        }
    }
    generateProtoTasks {
        all().each { task ->
            task.generateDescriptorSet = true
            task.builtins {
                // In most cases you don't need the full Java output
                // if you use the lite output.
                java {

                }

            }
            task.plugins {
                grpc { option 'lite' }
            }
        }
    }
}
afterEvaluate {
    project.tasks.findByName("compileJava").dependsOn(tasks.findByName("generateProto"))
    project.tasks.findByName("compileKotlin").dependsOn(tasks.findByName("generateProto"))
}
dependencies {
    implementation "org.glassfish:javax.annotation:10.0-b28"
    def grpcJava = '1.36.1'
    compileOnly "io.grpc:grpc-protobuf-lite:${grpcJava}"
    compileOnly "io.grpc:grpc-stub:${grpcJava}"
    compileOnly "io.grpc:grpc-core:${grpcJava}"
    File file = new File(projectDir, "depend.txt")
    if (!file.exists()) {
        return
    }
    def lines = file.readLines()
    if (lines.isEmpty()) {
        return
    }
    lines.forEach {
        logger.lifecycle("project:" + name + "   implementation: " + it)
        implementation(it)
    }
}

如果需要將proto編譯成java代碼,就需要依賴于com.google.protobuf插件,依賴于上面的build.gradle基本就可以將一個(gè)proto輸入編譯成一個(gè)jar工程。

另外我們需要把所有的proto文件拷貝到這個(gè)殼工程的src/main/proto文件夾下,最后我們會(huì)將buf.yaml中的name: buf.xxx.co/xxx/xxxxxx/xxx/xxxxxx轉(zhuǎn)化成工程名,去除掉一些無(wú)法識(shí)別的字符。

我們生成的模板工程如下:

其中proto.version會(huì)記錄proto內(nèi)的gitsha值還有文件的lastModified時(shí)間,如果輸入發(fā)生變更則會(huì)重新進(jìn)行一次文件拷貝操作,避免重復(fù)覆蓋的風(fēng)險(xiǎn)。

input.txt則包含了所有proto文件路徑,方便我們進(jìn)行開(kāi)發(fā)調(diào)試。

deps 轉(zhuǎn)化

由于proto之間存在依賴,沒(méi)有依賴則會(huì)導(dǎo)致無(wú)法將proto轉(zhuǎn)化成java。所以這里我講buf.yaml中讀取出的deps轉(zhuǎn)化成了一個(gè)depend.txt.

com.xxxx.api:google-protobuf:7.7.7

depend.txt內(nèi)會(huì)逐行寫(xiě)入當(dāng)前模塊的依賴,我們會(huì)對(duì)name進(jìn)行一次轉(zhuǎn)化,變成一個(gè)可讀的gradle工程名。其中7.7.7的版本只是一個(gè)缺省而已,并沒(méi)有實(shí)際的價(jià)值。

多線程操作

這里我們出現(xiàn)了一點(diǎn)點(diǎn)的性能問(wèn)題, 如果可以gradle插件中盡量多使用點(diǎn)多線程,尤其是這種需要io的操作中。

這里我通過(guò)ForkJoinPool,這個(gè)是ExecutorService的實(shí)現(xiàn)類。其中submit方法中會(huì)返回一個(gè)ForkJoinTask,我們可以將獲取gitsha值和lastModified放在這個(gè)中。之后把所有的ForkJoinTask放到一個(gè)數(shù)組中。

fun await() {
     forkJoins.forEach {
         it.join()
     }
 }

然后最后暴露一個(gè)await方法,來(lái)做到所有的獲取方法完成之后再繼續(xù)向下執(zhí)行。

另外則就是殼module的生成,我們也放在了子線程內(nèi)執(zhí)行。我們這次使用了線程池的invokeAll方法。

protoFileWalk.hashMap.forEach { (_, pbBufYaml) ->
           callables.add(Callable<Void> {
               val root = FileUtils.getRootProjectDir(settings.gradle)
               try {
                   val file = pbBufYaml.copyLib(File(root, "bapi"))
                   projects[pbBufYaml.projectName()] = file.absolutePath ?: ""
               } catch (e: Exception) {
                   e.printStackTrace()
                   e.message.log()
               }
               null
           })
       }
       executor.invokeAll(callables)

這里有個(gè)面試經(jīng)常出現(xiàn)的考點(diǎn),多線程操作Hashmap,之后我在測(cè)試環(huán)節(jié)隨機(jī)出現(xiàn)了生成工程和include不匹配的問(wèn)題。所以最后我更換了ConcurrentHashMap就沒(méi)有出現(xiàn)這個(gè)問(wèn)題了。

加載殼Module

這部分就和源碼編譯插件基本是一樣的寫(xiě)法。

projects.forEach { (s, file) ->
              settings.include(":${s}")
              settings.project(":${s}").projectDir = File(file)
          }

把工程插入settings 即可。

結(jié)尾

這部分方案這樣也就大概完成了一半,剩下的一半我們需要逐一把生層業(yè)務(wù)的依賴進(jìn)行一次變更,這樣就可以做到依賴最小化,然后也可以去除掉一部分無(wú)用的代碼塊。

以上就是ProtoBuf動(dòng)態(tài)拆分Gradle Module解析的詳細(xì)內(nèi)容,更多關(guān)于ProtoBuf拆分Gradle Module的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Flutter實(shí)現(xiàn)打印功能的示例詳解

    Flutter實(shí)現(xiàn)打印功能的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何通過(guò)?Flutter?實(shí)現(xiàn)調(diào)用打印機(jī)打印的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • MVVMLight項(xiàng)目之雙向數(shù)據(jù)綁定

    MVVMLight項(xiàng)目之雙向數(shù)據(jù)綁定

    這篇文章主要介紹了MVVMLight項(xiàng)目中雙向數(shù)據(jù)綁定的示例源碼及實(shí)現(xiàn)過(guò)程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步除夕快樂(lè),新年快樂(lè)
    2022-01-01
  • Android 7.0調(diào)用相機(jī)崩潰詳解及解決辦法

    Android 7.0調(diào)用相機(jī)崩潰詳解及解決辦法

    這篇文章主要介紹了 Android 7.0調(diào)用相機(jī)崩潰詳解及解決辦法的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • android使用SoundPool播放音效的方法

    android使用SoundPool播放音效的方法

    本篇文章主要介紹了android使用SoundPool播放音效的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • 玩轉(zhuǎn)Android之Drawable的使用

    玩轉(zhuǎn)Android之Drawable的使用

    這篇文章主要為大家詳細(xì)介紹了Android之Drawable的使用方法,幫助大家系統(tǒng)的學(xué)習(xí)一下Drawable的使用,感興趣的小伙伴們可以參考一下
    2016-06-06
  • 用Android實(shí)現(xiàn)京東秒殺功能詳解

    用Android實(shí)現(xiàn)京東秒殺功能詳解

    大家好,本篇文章主要講的是用Android實(shí)現(xiàn)京東秒殺功能詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • 一文帶你搞清楚Android游戲發(fā)行切包資源ID那點(diǎn)事

    一文帶你搞清楚Android游戲發(fā)行切包資源ID那點(diǎn)事

    這篇文章主要介紹了Android 解決游戲發(fā)行切包資源ID的一些問(wèn)題,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下
    2023-05-05
  • Flutter Http網(wǎng)絡(luò)請(qǐng)求實(shí)現(xiàn)詳解

    Flutter Http網(wǎng)絡(luò)請(qǐng)求實(shí)現(xiàn)詳解

    這篇文章主要介紹了Flutter Http網(wǎng)絡(luò)請(qǐng)求實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • SimpleCommand實(shí)現(xiàn)上傳文件或視頻功能(四)

    SimpleCommand實(shí)現(xiàn)上傳文件或視頻功能(四)

    這篇文章主要介紹了SimpleCommand實(shí)現(xiàn)上傳文件或視頻功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Android仿QQ消息提示點(diǎn)拖拽功能

    Android仿QQ消息提示點(diǎn)拖拽功能

    這篇文章主要為大家詳細(xì)介紹了Android仿QQ消息提示點(diǎn)拖拽功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01

最新評(píng)論

永登县| 霍林郭勒市| 林口县| 集安市| 晋中市| 喀什市| 上杭县| 蕲春县| 剑川县| 南陵县| 南京市| 富民县| 阿瓦提县| 玉环县| 常宁市| 昌都县| 高雄县| 阿巴嘎旗| 当涂县| 高雄市| 出国| 昌平区| 大宁县| 华蓥市| 施秉县| 永福县| 龙川县| 景德镇市| 莲花县| 滁州市| 田阳县| 布拖县| 江永县| 新余市| 西昌市| 黑龙江省| 喀喇| 遵义市| 余干县| 筠连县| 克拉玛依市|