简单的实现下通过gradle配置设置Android属性

ok,是我,又是我。主要还是将一天中模糊的知识点进行汇总处理。

早上,这个砖来一个一个需求,老板要求在版本号上面整一个打包日期,也没有要求太详细,就精确到天就好。emmm? 这个明显是不能手动改的,结合物理经验,无论是手动打包还是配置打包脚本,都需要基于gradle project,所以,这个方向就很明确了,这个写到build.gradle里面。那么如何整呢?

正文

我们先来整业务诉求,诉求很简单,每次gradle执行的时候,就存一个值到Android里面,方向有3个,

  • 往buildConfig中添加一个属性。
  • 往 AndroidMainifest 文件里面丢一个meta-data
  • 或者往resources 里面添加一个我们没有定义的 name

那么就开整,为了简单,那就直接写在 defaultConfig 闭包中。

BuildConfig

aidl 复制代码
        var format= DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDate.now())
        buildConfigField("String","myName","\"${format}\"")

可以看到,上面的代码的逻辑很简单,往buildConfig 中添加一个field,名称为myName,类型是String,值是格式化后的当前日期。

如果报错了,提示需要开启权限,那就在项目的gradle.properties中添加

aidl 复制代码
android.defaults.buildfeatures.buildconfig=true

先make project。调用的时候就直接BUildConfig.myName就可以了。 如果添加其他类型也是类似逻辑。

AndroidMainifest中的meta-data

首先我们需要先定义几个meta-data在AndroidManifest 中。

aidl 复制代码
        <meta-data android:name="my_demo" android:value="${my_demo}"/>
        <meta-data android:name="my_demo_1" android:value="${my_demo_1}"/>

同样在 defaultConfig 中添加:

aidl 复制代码
        // 写法1 
        manifestPlaceholders.put("my_demo","\"${format}\"")
        // 写法2,这个其实也是往manifestPlaceholders 这个map里面丢。
        addManifestPlaceholders(Map.of("my_demo_1","my_demo2"))

然后是获取meta-data的值:

aidl 复制代码
val  info=packageManager.getApplicationInfo(
            packageName, PackageManager.GET_META_DATA
        )
        info.metaData.keySet().forEach{
            LogUtils.e(it+"  ${info.metaData.get(it)}")
        }

可以看到ContextWrapper也有一个getApplicationInfo。但是这个获取到的metaData是空。所以还是得通过GET_META_DATA 获取。

通过添加res的方式

这个有一个前提是,定义的res的name及其type没有被定义。还是在defaultConfig中添加。

aidl 复制代码
        // string
        resValue("string","my_demo3","${format}")
        // boolean
        resValue("bool","my_demo4","true")
        // integer
        resValue("integer","my_demo5","5")
        // color
        resValue("color","my_demo6","#FFFFFFFF")

这个设置的字段必须是没有定义在res下面的,重新make project 在build/res/resValues/debug/values/gradleResValues.xml 就可以看到设置成功的内容了。 通常来说,值都应该用双引号保存。

其他方案

其他方案上来说,可能就是生成文件或者生成class的区别了。 生成文件,然后通过gradle 脚本复制到assets 目录下。生成的class 就需要放到指定的源码路径中了。

当然了也可以设置资源和class源码所在路径,那么就可以用到sourceSets。 在Android项目中,通过sourceSets可以配置代码和资源的放置位置。

sourceSets中的属性有:

  • java:指定Java代码的目录。
  • assets:指定资产文件的目录。
  • aidl:指定AIDL文件的目录。
  • jni:指定JNI文件的目录。
  • jniLibs:指定JNI库的目录。
  • manifest:指定清单文件的目录。
  • renderscript:指定RenderScript文件的目录。
  • res:指定资源文件的目录。
  • resources:指定资源文件的目录,与res功能相同。

除了上述属性外,sourceSets还可以通过setRoot(String path)方法,来显式指定特定的文件和目录。例如,如果在sourceSets中有多个目录,可以使用setRoot方法来设置根目录。 总之,sourceSets是Android项目中非常重要的配置项,可以根据需要灵活配置代码和资源的放置位置。

aidl 复制代码
    sourceSets {
        getByName("main"){
            println( jniLibs)
            println( java)
            println( assets)
            println( aidl)
            println( jni)
            println( jniLibs)
            println( manifest)
            println( renderscript)
            println( res)
            println( resources)
        }
        // getByName(main) 和下面这种写法是一致的。
        main {
            println( jniLibs)
            println( java)
            println( assets)
            println( aidl)
            println( jni)
            println( jniLibs)
            println( manifest)
            println( renderscript)
            println( res)
            println( resources)
        }
    }

扩展:渠道、马甲或多环境

既然都写到这里了,感觉要不把马甲包和多环境的配置一起整了吧。上面的知识很多时候都是整马甲包或者多环境配置来着。像今天这种小众的需求还是很少的。

那么这种差异化的需求,通常有两种方式:

  • 一种是整多个 buildType
  • 一种是整多个 productFlavors

buildType

通常而言,多网络环境用这个挺多的。写法有很简单:

java 复制代码
buildTypes {
    release {
        resValue("color","my_demo8","#FFFFFFFF")
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    debug {
        resValue("color","my_demo9","#FFFFFFFF")
        signingConfig signingConfigs.debug
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    text {
        resValue("color","my_demo6","#FFFFFFFF")
        signingConfig signingConfigs.debug
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

基于release或者debug 复制一个即可,然后在里面配置参数。

productFlavors

通常而言,这个主要是做马甲包,渠道包多一些,因为涉及到不同的目的切换不同的埋点,资源,cpu架构等等。 kotlin dsl 和groovy dsl 写法没有多少区别。都是基于flavorDimensions。所以:

aidl 复制代码
    // groovy 写法
    // 方式1
    //flavorDimensions.flavorDimensions.add("cpu")
    //flavorDimensions.flavorDimensions.add("channel")
    // 方式2
    flavorDimensions("cpu","channel")
    productFlavors {
        create("baidu"){
            dimension="channel"
        }
        create("x86"){
            dimension="cpu"
        }
    }

kotlin 设置 flavorDimensionList :

aidl 复制代码
flavorDimensionList.apply {
        add("channel")
        add("cpu")
    }

当然了,我们运行一个程序都需要选择以varinat 所以,我们可以基于varints统一配置固定的参数:

aidl 复制代码
    applicationVariants.configureEach {
        resValue("color","my_demo6","#FFFFFFFF")
    }

sourceSets

既然每次选择都会选择一个variant,所以sourceSets里面就可以拿到flavor自己设置。例如:

aidl 复制代码
    sourceSets {
        main {
            println( jniLibs)
            println( java)
            println( assets)
            println( aidl)
            println( jni)
            println( jniLibs)
            println( manifest)
            println( renderscript)
            println( res)
            println( resources)
        }
        baidu{
            println("baidu:" +java)
        }
    }

总结

可以看到上面很多printlin,写printlin()的意思是这个可以被执行。只要可以执行到那个闭包中,那么具体实现就是想象空间了。嗯,整体来说还是蛮简单的,主要还是扩充认知,遇到了可以多一种选择罢了。

嗯,今天又没有卡12点,完美。

相关推荐
服装学院的IT男4 小时前
【Android 13源码分析】Activity生命周期之onCreate,onStart,onResume-2
android
Arms2064 小时前
android 全面屏最底部栏沉浸式
android
服装学院的IT男4 小时前
【Android 源码分析】Activity生命周期之onStop-1
android
ChinaDragonDreamer6 小时前
Kotlin:2.0.20 的新特性
android·开发语言·kotlin
网络研究院9 小时前
Android 安卓内存安全漏洞数量大幅下降的原因
android·安全·编程·安卓·内存·漏洞·技术
凉亭下9 小时前
android navigation 用法详细使用
android
小比卡丘11 小时前
C语言进阶版第17课—自定义类型:联合和枚举
android·java·c语言
前行的小黑炭12 小时前
一篇搞定Android 实现扫码支付:如何对接海外的第三方支付;项目中的真实经验分享;如何高效对接,高效开发
android
落落落sss14 小时前
MybatisPlus
android·java·开发语言·spring·tomcat·rabbitmq·mybatis
代码敲上天.14 小时前
数据库语句优化
android·数据库·adb