简单的实现下通过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点,完美。

相关推荐
消失的旧时光-19431 小时前
Android 接入 Flutter(Add-to-App)最小闭环:10 分钟跑起第一个混合页面
android·flutter
城东米粉儿1 小时前
android StrictMode 笔记
android
Zender Han1 小时前
Flutter Android 启动页 & App 图标替换(不使用任何插件的完整实践)
android·flutter·ios
童无极2 小时前
Android 弹幕君APP开发实战01
android
赛恩斯2 小时前
kotlin 为什么可以在没有kotlin 环境的安卓系统上运行的
android·开发语言·kotlin
于山巅相见2 小时前
【3588】Android动态隐藏导航栏
android·导航栏·状态栏·android11
乡野码圣2 小时前
【RK3588 Android12】开发效率提升技巧
android·嵌入式硬件
eybk2 小时前
Beeware生成安卓apk取得系统tts语音朗读例子
android
zhangphil3 小时前
Android图像显示,CPU的Skia与GPU的Vulkan高性能渲染系统
android