Gradle学习笔记

Android Gradle基础介绍,Android面试送分题 android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion } 1 2 3 4 Android studio gradle Task //构建 gradlew app:clean //移除所有的编译输出文件,比如apk gradlew app:build //构建 app module ,构建任务,相当于同时执行了ch 阅读详情

gradle学习笔记(一)

概念

Gradle本身是基于Groovy脚本语言进行构建的,并通过Domain Specific Language(DSL语言)进行描述和控制构建逻辑的。
参考的文档:

  1. 官方文档
  2. 中文翻译文档
  3. Gradle用户指南
  4. Android Studio构建指南
  5. Android Studio Gradle,插件使用指南
  6. Gradle DSL语言API

gradle初探

项目全局build.gradle

文件中最重要的就是buildscript的部分代码。在buildscript中,Gradle制定了使用jcenter代码仓库,同事声明了依赖的Android Gradle插件版本。
在allprojects领域中,开发者可以为项目整体配置一些属性。

Module build.gradle

Gradle使用的是DSL语言,它是针对某个领域所设计出来的特定的语言,因为有了领域的限制,要解决的问题就被划定了范围。因此要针对每个特定的领域进行分析即可。

  • apply plugin 领域
    apply plugin 这块领域描述了Gradle所引入的插件。
    apply plugin:'com.android.application'表示该module是一个Android Application。这个插件包含了Android项目相关的所有工具。

  • android 领域
    android{...}这块领域描述了该Android module构建过程中所用到的所有参数。默认情况下,IDE自动创建了compileSdkVersion、buildToolsVersion这两个参数,分别对应变异的SDK版本和ANDROID build tools版本。而在android领域内,系统还默认创建了两个领域—defaultConfig和buildTypes,这两个领域。

  • dependencies 领域
    dependencies{...}这块领域描述了该Android module构建过程中所依赖的所有库,库可以是以jar的形式进行以来,或者是使用Android推荐的aar形式进行依赖。aar相对于jar具有不可比拟的优势,不仅配置以来更加简单,而且可以将图片的资源文件放入aar中供主项目依赖,几乎等同于依赖源码。

Gradle Task

  1. 查看工程有哪些Task:./gradlew task
  2. 各个Task的具体作用与各个Task之间的相互调用关系:./gradlew task -all
  3. assemble task用于组合项目的所有输出,包含了assembleDebug和assembleRelease两个Task
  4. check task 用于执行检查任务
  5. build Task 类似一个组合指令,执行了check和assemble的所有工作
  6. clean task 用于清理所有中间编译结果,这个指令使用的非常广泛。

Gradle进阶

构建全局配置

  • 全局参数
    在项目根目录下的build.gradle中,通过ext领域可以指定全局的配置信息,代码如下所示:
ext{
    compileSdkVersion = 23
    buildToolsVersion = "23.0.2"
    minSdkVersion = 14
    targetSdkVersion = 23
    versionCode = 3
    versionName = "1.0.1"
}
  • 引用配置
    在配置好全局参数后,就可以在每个module中使用这些配置了,例如

compileSdkVersion rootProject.ext.compileSdkVersion

方法非常简单,通过rootProject.ext可以引用所有的全局参数。
另外,开发者也可以把ext全局配置卸载allprojects领域中,这样在每个module中就可以直接引用申明的变量了。

allprojects{
    repositores{
        jecnter()
    }
    ext {
        COMPILE_SDK_VERSION = 22
    }
}

这样写的好处是可以将配置进行统一管理。但坏处是如果这样写的话,Gradle的版本更新通知检查机制就无限了。大部分时候,这种写法是利大于弊的。

构建defaultConfig

defaultConfig{
    applicationId "com.xxx.xxx"
    minSdkVersion 14
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}

这些设置替换了AndroidMainifest文件中的属性。除此之外可以动态控制VersionName的生成。

defaultConfig{
    applicationId "com.xxx.xxx"
    minSdkVersion 14
    targetSdkVersion 23
    versionCode 1
    versionName getCustomVersionName()
}

def getCustomVersionName(){
    ...
}

构建buildTypes

通过创建不同的构建类型,从而生成不同类型的apk,可以帮助开发者完成很多事情。例如实现只有在debug类型下才开启的功能,如调试、Log等功能,以及为不同构建类型实现不同的参数配置,等等。

  • 构建类型基础
buildTypes{
    release{
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'),`proguard-rules.pro`
    }
}

除了系统默认的构建type–debug和release之外,gradle同样支持自定义创建新的构建类型。例如,在脚本中添加一个xys类型,同时设置该类型的applicationIdSuffix的参数为”.xxx”,代码如下:

buildTypes{
    release{
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'),`proguard-rules.pro`
    }
    xxx{
        applicationIdSuffix ".xys"
    }
}

执行./gradlew build之后再build目录中多生成了一个app-xxx-unsigned.apk,这个就是自定义的新的buildType-xys类型。那么applicationIdSuffix参数的作用是什么呢?在Android系统中,系统是通过包名来区分应用的。如果应用的包名相同,那么就意味着这是一个应用。因此在构建类型的时候,可以指定applicationIdSuffix参数为默认的包名增加一个后缀。例如前面例子中的”.xxx“,以此区分不同的构建类型。类似的方式,还可以给debug版本增加”.debug“的后缀,给release版本增加”.release”的后缀。

  • 构建类型buildTypes的继承
buildTypes{
    release{
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'),`proguard-rules.pro`
    }
    xxx.initWith(buildTypes.debug)
    xxx{
        applicationIdSuffix ".xxx"
    }
}

构建signingConfigs

Android Apk使用签名来保证App的合法性。android系统有一个默认的debug签名,debug包会默认使用这个debug签名进行签名。那么当你需要给其他版本设置签名的时候,就需要自己来配置signingConfigs领域

生成签名

生成签名有两种:

  1. 命令
  2. android studio

生成的签名文件是xxx.jks文件。对于企业项目来说,这个key通常是存放在打包服务器上的,那么在gradle脚本中,就需要通过具体的路径来访问。这一点与访问各种配置文件的方式是一样的。

  • 配置签名
    生成了签名文件后,就可以在build.gradle脚本的android领域中配置签名的相关参数
signingConfigs{
    xxx{
        storeFile file("xxx_key.jsk")
        storePassword "12344567"
        keyAlias "xxx"
        keyPassword "1234567"
    }
}

配置的信息就是前面在创建签名时填写的信息。需要注意的是,签名信息一定要包含在一个领域中,你可以给这个领域起一个名字,例如在这里的”xxx“(通常情况下,会使用debug,release这样的签名)。

  • 使用签名
    配置好相关的签名信息后,就可以在构建类型的时候加入签名的设置。这样生成的apk就会包含签名版和未签名版两种,完整的配置如下所示。
signingConfigs{
    xxx{
        storeFile file("xxx_key.jsk")
        storePassword "12344567"
        keyAlias "xxx"
        keyPassword "1234567"
    }
}

buildTypes{
    release{
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'),`proguard-rules.pro`
    }

    xxx{
        signingConfig signingConfigs.xxx
        applicationIdSuffix ".xxx"
    }
}

Anroid领域中的可选配置

在Android领域中,还有一些可选的配置。在具体的开发场景中,开发者可以根据自己的需要进行配置。

  • compileOptions
    配置编译的选项,类似于compileSdkVersion。不是设置Android SDK的选项,而是设置Java的编译选项,通常可以在这里指定Java的编译版本。
compileOptions{
    sourceCompatibility Java Version.VERSION_1_8
    targetCompatibility Java Version.VERSION_1_8
}

指定编译版本,通常是为了使用某些版本中的一些语言新特性。

  • lintOptions

Lint代码检查,这个选项打开,在编译的时候,会因为Lint的error而终止。

构建Proguard

Proguard配置是Android的apk混淆文件配置,但它的作用绝对不仅仅是混淆代码。他同样可以精简代码、资源,优化代码结构。

buildTypes{
    release{
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'),`proguard-rules.pro`
    }
    xxx{
        signingConfig signingConfigs.xxx
        applicationIdSuffix ".xxx"
    }
}

Gradle动态参数配置

Gradle既然是一种脚本配置语言,那么它一定可以通过配置文件动态配置其编译脚本,列入前面在配置签名脚本时,使用的代码如下所示。

signingConfigs{
    xxx {
        storeFile file("xxx_key.jsk")
        storePassword "12344567"
        keyAlias "xxx"
        keyPassword "1234567"
    }
}

使用gradle.properties文件来配置脚本的动态参数。

System.properties方式

在gradle.properties文件中添加以下配置

systemProp.keyAliasPassword=1234567
systemProp.keyAlias=xxx
systemProp.keyStorePassword=1234567
systemProp.keyStore=xxx_key.jks

这些配置实际上就是之前写死的配置参数,只不过这里把它们配置到了systemProp中,那么在build.gradle脚本进行引用的时候,就可以通过System.properties[KEY]获取这些参数。

signingConfigs{
    xxx {
        storeFile file(System.properties['keyStore'])
        storePassword System.properties['keyStorePassword']
        keyAlias System.properties['xxx.keyAlias']
        keyPassword System.properties['xxx.keyAliasPassword']
    }
}

通过project.property(Key)方法,就可以去除对应的Value。这种方式与使用System.properties的方式基本一样。

多渠道打包

所谓多渠道打包,实际上就是在代码层面上标记不同的渠道名,从而便于统计不同的应用市场该apk的下载量。而且有些时候有些暴还可以以从网页的外链接或者一些非市场的渠道进行下载。这些都需要进行统计,因此多渠道打包,变成了打包任务的重中之重。
利用Gradle进行多渠道打包,将开发者从之前繁杂的ant打包中解放出来。Gradle的强大功能,将多渠道打包变得异常简单,只需要在Gradle脚本中进行简单配置,即可完成多渠道打包。

  • 创建渠道占位符
    首先AndroidMainifest文件的Application节点下,创建如下所示的meta-data节点
<meta-data
    android:name="PRODUCT"
    android:value="${CHANNEL_VALUE}"/>

其中”${CHANNEL_VALUE}“就是要进行替换的渠道占位符。

  • 配置Gradle脚本
    在项目的Gradle脚本的android领域中,添加productFlavors领域,并添加定义的渠道名。同时,使用manifestPlaceholders指定要替换渠道占位符的值。
productFlavors{
    product1{
        manifestPlaceholders=[CHANNEL_VALUE:"PRODUCT1"]
    }
    product2{
        manifestPlaceholders=[CHANNEL_VALUE:"PRODUCT2"]
    }
    product3{
        manifestPlaceholders=[CHANNEL_VALUE:"PRODUCT3"]
    }
}

实际上除了渠道名,AndroidMainifest文件中的其他设置,同样可以使用占位符进行配置。只要利用manifestPlaceholders进行替换即可,原理与多渠道类似。这一个技巧可以让项目能够直接在编译脚本–build.gradle中进行动态参数控制,便于统一管理。更进一步,在Module中同样可以进行这些动态参数的控制。例如某些Module的封装,需要配置一些炎症Key作为参数,如果这些Key卸载Module中,Module就是去了通用性。因此借助manifestPlaceholders,开发者可以将动态参数配置到Module中,通过主项目的manifestPlaceholders。可以参考博客

脚本优化

productFlavors{
    product1{
        manifestPlaceholders=[CHANNEL_VALUE:"PRODUCT1"]
    }
    product2{
        manifestPlaceholders=[CHANNEL_VALUE:"PRODUCT2"]
    }
    product3{
        manifestPlaceholders=[CHANNEL_VALUE:"PRODUCT3"]
    }
}
productFlavors.all{flavor->
    flavor.manifestPlaceholders=[CHANNEL_VALUE:name]        
}

增加的productFlavors.all领域对所有的productFlavors进行遍历,并使用其name作为渠道名。这些name实际上就是produce1,Produce2,produce3

生成重命名包

在生成渠道包后,包的明明通常是默认命名,即app-渠道名-buildType.apk。但是通常情况下,项目经理都会要求对报名进行重命名,以满足市场部的需求。那么这时候就可以通过Gradle脚本进行快速重命名,而不需要再使用rename指令或者Python指令或者Python脚本进行修改

application Variants.all{variant ->
    variant.outputs.each{ output ->
        if(output.outputFile != null &&
                        output.outputFile.name.endsWith('.apk') &&
                        'release'.equals(variant.buildType.name)){
                            def apkFile = new File(output.outputFile.getParent(),
                                "XXXApp_${variant.flavorName}_ver${variant.versionName}.apk")
                            output.outputFile = apkFile
                        }
    }

}

将这段脚本放到android领域中即可,当执行gradle build指令时该task也会执行,与多渠道优化的那段代码非常类似,它去除了所有的生成的apk包,并判断其文件是否是apk、是否是release版本。如果是,则重新将其命名为”XXXApp_渠道名_ver版本号.apk“。代码其实非常简单,但难就难在对groovy语言的理解和gradle android插件的熟悉度上。很多系统变量和内置变量。

为不同版本添加不同代码

在开发中,不同的版本通常有不同的代码功能。例如最常用的Log开关,在debug版本中会打印开发日志,而在release版本中需要关闭的。因此,一般会有一个全局的变量开关,根据不同的版本设置不同的值。这一切在gradle脚本的支持下,仅仅变成了一句配置。

buildTypes{
    rlease{
        buildConfigField "boolean","testFlag","true"
        minifyEnabled true
        shrinkResources ture
        proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
    }
    xxx{
        buildConfigFiles "boolean","testFlag","false"
        signingConfig signingConfigs.xxx
        applicationIdSuffix ".xxx"
    }
}

通过制定buildConfigField的三个参数–类型、名称、值,就可以将一个变量设置到不同的buildType中去。打开系统的BuildConfig类,可以看到不同buildType下对应的testFlag的值。该文件对应的路径为/项目/app/build/generated/source/buildConfig/(你也可以通过双击Shift进行快速查找)
直接通过BuildConfig类,就可以获取到不同buildType所对应的值了。如果是String类型的变量,在写入字符串的时候,需要加入转义字符。

buildConfigField "String","myname","\"abs\""

除了Java代码可以使用这种方式进行添加之外,资源文件同样可以进行分版本设置属性值。例如要给不同的版本设置不同的AppName

defaultConfig{
    ....
    resVaule("string","app_name","XXXApp")
}
buildTypes{
    release{
        ...
        resVaule("string","app_name","XXXAppRelease")
    }
    debug{
        ...
        resVaule("string","app_name","XXXAppDebug")
    }
}
defbuildTime(){
    return new Date().format("yyyy-MM-dd HH:mm:ss")
}
defaultConfig{
    resValue "String","build_time",buildTime()
}

在上面的代码中,定义了一个buildTime方法,并赋值给自定义的build_time变量。这时候不需要在Java代码中增加变量,即可直接引用已经编译到R文件中的变量build_time,代码如下:

Log.d("test",getString(R.string.build_time))

Gradle多项目依赖

  • build.gradle:控制每个module的编译过程。
  • gradle.properties:设置Gradle脚本中的参数。
  • local.properties:Gradle的SDK相关环境变量配置。
  • settings.gradle:配置Gradle的多项目管理。

使用Gradle上传aar到Maven库

开发者可以将自己开发的库项目上传到Maven库,供其他程序调用。上传的方式为通过脚本进行提交

uploadArchives{
    repositories{
        mavenDeployer{
            pom.groupId = GROUPID
            pom.artifactId = ARTIFACTID
            if(System.properties['isRelease'].toBooleans()){
                pom.version = VERSION
                repository(url: nexusReleases){
                    authentication(userName:nexusUsername,password:nexusPassword)
                }
            }else{
                pom.version = "${VERSION}-SNAPSHOT"
                repository(url:nexusSnapshots){
                    authentication(userName:nexusUsername,password:nexusPassword)
                }
            }
            pom.project{
                descriptoin 'xxxx'
            }
        }
    }
}

同时,还需要在gradle.properties文件中进行参数的配置

GROUP_ID = com.xxxx.cccc
ARTIFACT_ID = aaaa
VERSION = 1.x.xxx
RELEASE_REPOSITORY_URL = maven url
nexusUsername = username
nexusPassword = password
systemProp.isRelease = true

Gradle 依赖管理

  • 强制刷新配置
compile('com.xxx.xxx:3.0.1-SNAPSHOT@aar'){
    transitive = true
}

如果增加一个属性transitive并让其值为true,则代表会强制刷新远程库,避免远程库更新后本地未刷新的问题。

Gradle依赖传递

在使用Gradle aar文件时,京城会发生这样的情况,主项目A依赖库项目B,库项目B依赖库项目C和jar包D。这时候主项目在引用库项目B时,写成如下所示的方式。

compile 'com.xxx.xxxx:xxxx:1.0.0-SNAPSHOT'

这样的写法也是一般引用库项目的标准写法,其表示B项目及其依赖的所有项目,即C和D。那么如果C或者D出现重复依赖的问题,或者主项目只想依赖库项目B而不像依赖库项目B所以来的项目,则可以使用@aar关键字关闭依赖传递,使用方法如下所示。

compile 'com.xxx.xxxx:xxxx:1.0.0-SNAPSHOT@aar'

如果这样引用库项目B,则不会进行依赖传递。但要注意的是,libs目录下的jar文件时不受影响的,开发者在使用过程中需要非常注意。
另外,还可以使用exclude module排除一个库中引用的其他库,例如aar库A依赖了B和C,此时可以通过以下的方式进行依赖。

compile('com.xxx.yyy:aaa:1.1.1'){
    exclude module:'com.xxx.yyy.bbb:1.1.2'
}

传递依赖问题是使用Gradle时一定会遇到的问题,不仅仅是依赖传递的库会冲突,而且也会发生资源冲突的问题。因此遇到Gradle编译错误的时候,一定要仔细分析错误的原因,找到冲突的根本原因从而去解决问题

Gradle依赖统一管理

Gradle引用依赖非常简单,但一旦涉及多module,每个module的依赖管理就变得非常麻烦。这就和编程中使用的变量一样,每个module中都引用自己的依赖-局部变量,这样就造成多个module有多个局部变量,不利于项目管理。因此,最好是使用类似全局变量的方式来进行统一的管理。
在根目录的build.gralde脚本中配置如下所示的代码。

ext{
    android=[compileSdkVersion:23,
            buildToolsVersion:'23.0.2']

    dependencies = [supportv7:'com.android.support:appcompat-v7:23.2.0']
}

在全局Gradle脚本中,指定了android和dependencies两个列表,并在其中配置了统一的参数和对应的值。这样在每个module中,一颗通过代码使用全局的依赖配置。

android{
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.android.buildToolsVersion
}
dependencies{
    compile rootProject.ext.dependencies.supportv7
}

更进一步,开发者还可以把这些全局参数抽取出来,写到一个单独的配置文件中。例如,比这在项目根目录下创建一个config.gradle文件,并写入如下所示的代码

ext{
    android = [compileSdkVersin:23,
                buildToolsVersion:'23.0.2']
    dependencies=[supportv7:'com:android.support:appcompat-v7:23.2.0']
}

这里就要把ext全局参数抽取出来了。下一步,在根目录下的build.grdle文件中,使用代码加载这个配置文件,代码如下所示。

apply from:'config.gradle'

这样就可以在所有的子module中使用这些参数了,通过这种统一的依赖管理方式,可以统一所有module的依赖配置,避免使用不同版本的依赖库而导致的冲入,而且也利于项目的管理。

Gradle使用技巧

  • Debug模式禁用掉Lint./gradlew build -x lint,其中-x参数表示排除掉一个Task,即Lint。通过这种方式可以实现禁止Lint的执行。
  • Debug模式禁用AAPTaaptOptions.cruncherEnabled = false。
  • 官方文档

Gradle加速

Gradle在编译时会执行大量的Task,同时生成很多中间文件。因此磁盘IO会造成编译速度缓慢。解决该问题的最好办法就是为电脑更换固态硬盘,增加磁盘的IO速度。同时尽量减少本地库项目的依赖,多实用aar进行依赖。
在gradle.properties文件中增加如下代码

org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true

同时,在build.gradle中增加如下代码

dexOptions{
    incremental true
        javaMaxHeapSize "4g"
}

gradle.properties文件中的代码,表示开启Gradle的多线程和多核心支持。而build.gradle中的代码,表示开启Gradle的增量编译,增加编译的内存资源的4G。

Gradle自定义插件

Gradle提供了强大的插件自定义功能,可以在某些情况下通过自定义插件实现自己的一些功能。官方文档

在Gradle中创建自定义插件,Gradle提供了以下三种方式。

  • 在build.gradle脚本中直接使用
  • 在buildSrc中使用
  • 在独立Module中使用

Gradle插件可以在IDEA中进行开发,也开一在Android Studio中进行研发。他们唯一不同就是IDEA提供了Gradle开发的插件,比较方便创建文件和目录。而在Android studio中,开发者需要手动创建。

Gradle 打包配置

编译时报重复文件的错误

// 1. pickFirsts:当出现重复文件,会使用第一个匹配的文件打包进入。
// 2. merges:当出现重复文件,合并重复的文件打入APK,两个文件会进行拼接
// 3. excludes:打包的时候排除匹配的文件

packagingOptions {
    pickFirst 'lib/armeabi-v7a/libyuv.so'
    merge 'lib/armeabi-v7a/libyuv.so'
    exclude 'lib/armeabi-v7a/libyuv.so'
}
Gradle学习笔记 使用Gradle Wrapper Gradle可以在没有安装Gradle的情况下使用,这时候就需要Gradle Wrapper了。Gradle Wrapper其实就是一个脚本文件,它会在没有安装Gradle的情况下为我们下载Gradle,之后我们就可以使用gradlew命令,像使用gradle一样来使用Gradle了。但是对于我们天朝用户来说,不管是Gradle还是Gradle Wrapper,都需要网络代理才能以较高的速度下载。创 阅读详情

相关推荐

Redis中什么是Big Key(大key)问题?如何解决Big Key问题?

通俗易懂的讲,Big Key就是某个key对应的value很大,占用的redis空间很大,本质上是大value问题。key往往是程序可以自行设置的,value往往不受程序控制,因此可能导致value很大。redis中这些Big Key对应的value值很大,在序列化/反序列化过程中花费的时间很大,因此当我们操作Big Key时,通常比较耗时,这就可能导致redis发生阻塞,从而降低redis性能。用几个实际的例子对大Key的特征进行描述:● 一个String类型的Key,它的值为5MB(数据过大); ● 一

weixiaohuai的博客 3万+

【android混淆代码】android 混淆 minifyEnabled 设置为false

项目在pgy上编包给测试的小伙伴使用,结果时候登陆不进去,老弹滑动验证错误,但是本地是一切正常的。

weixin_44002043的博客 1157

华为海思2026届数字IC秋招笔试高频考点解析与实战技巧(2025最新版)

本文深入解析华为海思2026届数字IC秋招笔试的高频考点与实战技巧,涵盖时序优化、低功耗设计、DFT规则等核心模块。针对2025年最新真题,提供详细的解题思路和工程经验,帮助考生高效备考。特别关注SystemVerilog约束随机测试等新增考点,助力考生在秋招笔试中脱颖而出。

m2n3o4p5的博客 414

使用gradle的productFlavors实现Android项目多渠道打包

productFlavors 用法productFlavors顾名思义,就是用来分别定义产品不同的特性,使用它可以用一套代码创建不同的产品 就是用于定义产品的特性,这是每个产品不同的地方。有了它我们可以用同一套代码创建不同的产品。设置productFlavors的方法如下: 在build.gradle中加入productFlavors结构 在app(module)目录下的build.grad

提辖鲁的博客 7460

计组实验之四路表决器

请在之前四路表决器电路实现的基础上,继续用连接线 联接CD4511,将投票为1的票数总和显示到一个 LED上,思考如何做?由于我们需要通过显示字形来直接看出有几个1,在这里,我们最多有四个1,即显示字形最多到4就行,所以我们需要将有几个1用2进制数来表示,下面给出了相关电路图。显示输入插口,按真值表(自拟)要求,逐次改变输入变量, 测量相应的输出值,验证逻辑功能, 与表3-1 进行比较, 验证所设计的逻辑电路是否符合要求。用实验结果与真值表3-1和3-2进行比对,可以得出,我们实验结果是正确的。

szyugly的博客 1万+

Windows10内核逆向-2-KiSystemCall64的调用流程剖析

本文深入剖析了Windows 10 x64系统中KiSystemCall64函数的完整调用流程。从用户态触发syscall指令开始,详细讲解了如何通过swapgs切换内核栈、构建KTRAP_FRAME陷阱帧、进行SMAP/CFG等安全检查,到最终通过SSDT寻址并执行目标系统服务的全过程,揭示了系统调用从Ring 3到Ring 0切换的核心机制与安全设计。

weixin_29209805的博客 82

Android Gradle使用详解(七) 之 多渠道构建你的App

1 背景 在国内手机厂商应用市场和第三方手机应用市场如此泛滥的环境下,针对不同的应用市场区分个别特殊功能、跟踪活跃留存这些数据来源,等。这时构建区分App渠道是很有必要的。Android Gradle中提供了ProductFlavors{}闭包配置来帮助我们很好的处理多渠道构建的问题和实现批量自动化,关于ProductFlavors{}我们在之前的博文《Android Gradle使用详解(三)...

子云心的博客 3088

Cartographer参数调优指南:如何用Lua配置解决建图漂移问题

本文深入解析Cartographer SLAM系统的Lua参数调优方法,针对建图漂移问题提供完整解决方案。从运动滤波、扫描匹配到多传感器融合,详细讲解关键参数配置技巧,并给出仓库物流和服务机器人等典型场景的优化方案,帮助开发者实现精准建图。

vulkan6gpu的博客 114

教你如何玩转 AndroidStudio 一键多渠道打包

如果你还在手动的对每个市场进行打包,先不说 Low 不 Low,自己也会觉得很痛苦对吧,甚至有的同学使用 Windows build 打包一次就得 3-5min;打 6 个市场包半个小时就过去了,最重要的是这个过程中还有可能出现错误,增加测试的难度与成本。多渠道打包也有很多种方式;有远程的 jenkins + gradle +github 等方法;网上资料很多,由于这种方式需要的配置环境比较繁琐;适

JackWaiting 2792

【JS】自定义上传组件,文件上传与回显,自定义进度条显示(基于element-plus与axios)

公司是做B 端产品的,有sass平台也有源码交付的项目,最近开发了很多小系统,这里记录一下开发遇到的问题。 需要定制一个上传组件,要求可以自定义文件存储路径,自定义可上传的文件类型,限制文件大小等,并且提供基础的文件回显功能,例如上传一张图片到服务器指定目录的`/file`文件夹下面,并且实现可以查看预览的功能。

余浩的博客 1160

ADXL355 STM32 HAL 库 SPI 驱动实战:从零构建高精度加速度数据采集系统

本文详细介绍了如何使用STM32 HAL库通过SPI接口驱动ADXL355高精度加速度计,构建稳定可靠的数据采集系统。从硬件连接到寄存器配置,再到数据采集与处理,提供了完整的实战代码和优化技巧,特别适合工业级振动监测等应用场景。

weixin_28738397的博客 324

【Gradle:新一代构建工具】学习笔记 3 Gradle进阶说明 3.2 Gradle中的settings.gradle文件说明

【Gradle:新一代构建工具】学习笔记 3 Gradle进阶说明 3.2 Gradle中的settings.gradle文件说明

代码改变世界 1043

系统架构设计师备考攻略

计算机软件资格考试是由国家人力资源和社会保障部、工业和信息化部领导下的国家级考试。 软考没有学历、专业、年龄、相关工作经验要求,你可以根据自身选择合适的去报名(也就是说你直接直接报高级),但是一次考试只能报一种。 计算机软件资格考试纳入全国专业技术人员职业资格证书制度的统一规划,实行统一大纲、统一试题、统一标准、统一证书的考试办法,每年举行两次。通过考试获得证书的人员,表明其已具备从事相应专业岗位工作的水平和能力,用人单位聘任相应专业技术职务(助理工程师、工程师、高级工程师)。

帅次的博客 7154

gradle学习笔记

需要注意的是:gradle 的指令要在含有build.gradle 的目录执行。比如:1、编译业务代码和配置文件会生成build目录2、gradle test 编译测试代码,生成测试报告在某种程度上,Groovy 可以被视为Java 的一种脚本化改良版,Groovy 也是运行在 JVM 上,它可以很好地与 Java 代码及其相关库进行交互操作。它是一种成熟的面向对象编程语言,既可以面向对象编程,又可以用作纯粹的脚本语言。

furenqiang的博客 1988

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【Gradle:新一代构建工具】学习笔记 3 Gradle进阶说明 3.24 Gradle中的项目发布

【Gradle:新一代构建工具】学习笔记 3 Gradle进阶说明 3.24 Gradle中的项目发布

代码改变世界 455

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Android Gradle 学习笔记整理

ismany‘’’println s1println s2println s3通过上述的一些入门讲解,大概知道了gradle是怎么构建的,那现在来自定义一个安卓打包过程中,重命名APP名字的一个插件。上述在build.gradle直接编写Plugin是OK的,那么为了复用性更高一些,那我们怎么把这个抽出去呢?如下其中build.gradle为jcenter()uploadArchives{ //当前项目可以发布到本地文件夹中。

2401_87287212的博客 740

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【Gradle:新一代构建工具】学习笔记 3 Gradle进阶说明 3.31 Gradle多模块项目案例演示【基于SSM】

【Gradle:新一代构建工具】学习笔记 3 Gradle进阶说明 3.31 Gradle多模块项目案例演示【基于SSM】

代码改变世界 458

学习笔记 - 5步理解Gradle. How build execution is controlled by gradle tasks?

https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:projects_and_tasks https://docs.gradle.org/current/userguide/build_lifecycle.html 这是来自官网的学习笔记,含有很多复制粘贴,链接也都贴在上面和文章超链接里了 1. Five ...

creepcheck的博客 1298

【Gradle:新一代构建工具】学习笔记 3 Gradle进阶说明 3.28 使用Gradle创建SpringBoot项目

【Gradle:新一代构建工具】学习笔记 3 Gradle进阶说明 3.28 使用Gradle创建SpringBoot项目

代码改变世界 544

75Gradle学习笔记

Gradle学习笔记 文章目录1 Gradle简介2 Gradle环境搭建2.1 下载2.2 安装2.3 配置2.3.1 新建变量GRADLE_HOME2.3.2 新建变量GRADLE_USER_HOME2.3.3 添加变量到path2.3.4 修改配置2.3.5 验证安装是否成功2.3.5 Gradle配置本地仓库2.3.6 Gradle配置远程仓库2.3.7 IDEA中配置Gradle2.4 Gradle新建Java工程2.5 Gradle新建Web工程3 groovy基...

tangguanlin2008的博客 1019

Gradle学习笔记 Gradle命令行

执行多个任务安装好Gradle之后,就可以使用Gradle命令行了。首先我们先新建一个文件夹gradle-learn,然后在其中新建一个build.gradle,这是Gradle的项目构建文件。task compile { doLast { println 'compiling source' } }task compileTest(dependsOn: compil

乐百川 1万+

Gradle 学习笔记

学习中

weixin_48011779的博客 586
上一篇: AOP在Android中最佳用法
下一篇: Android 投影MAC,Vysor pro 破解
Bobby_lyc
博客等级 码龄16年 1164粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值