Android Gradle Plugin指南(二)——基本项目

【Android 修炼手册】Gradle 篇 -- Android Gradle Plugin 主要 Task 分析(1) 下面是有几位Android行业大佬对应上方技术点整理的一些进阶资料。希望能够帮助到大家提升技术高级UI,自定义ViewUI这块知识是现今使用者最多的。当年火爆一时的Android入门培训,学会这小块知识就能随便找到不错的工作了。不过很显然现在远远不够了,拒绝无休止的CV,亲自去项目实战,读源码,研究原理吧!《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!** 阅读详情

原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Basic-Project


3、Basic Project(基本项目)


一个Gradle项目的构建过程定义在build.gradle文件中,位于项目的根目录下。

3.1 Simple build files(简单的构建文件)


一个最简单的Gradle纯Java项目的build.gradle文件包含以下内容:

apply plugin: 'java'

这里引入了Gradle的Java插件。这个插件提供了所有构建和测试Java应用程序所需要的东西。 

最简单的Android项目的build.gradle文件包含以下内容: 

buildscript {
        repositories {
            mavenCentral()
        }

        dependencies {
            classpath 'com.android.tools.build:gradle:0.11.1'
        }
    }

    apply plugin: 'android'

    android {
        compileSdkVersion 19

        buildToolsVersion "19.0.0"

    }

这里包括了Android build file的3个主要部分: 

buildscrip{...}这里配置了驱动构建过程的代码。 
在这个部分,它声明了使用Maven仓库,并且声明了一个maven文件的依赖路径。这个文件就是包含了0.11.1版本android gradle插件的库。 
注意:这里的配置只影响控制构建过程的代码,不影响项目源代码。项目本身需要声明自己的仓库和依赖关系,稍后将会提到这部分。 

接下来,跟前面提到的Java Plugin一样添加了android plugin。 

最后,andorid{...}配置了所有android构建过程需要的参数。这里也是Android DSL的入口点。 
默认情况下,只需要配置目标编译SDK版本和编译工具版本,即compileSdkVersion和buildToolsVersion属性。 
这个complieSdkVersion属性相当于旧构建系统中project.properites文件中的target属性。这个新的属性可以跟旧的target属性一样指定一个int或者String类型的值。 

重要:你只能添加android plugin。同时添加java plugin会导致构建错误。 

注意:你同样需要在相同路径下添加一个local.properties文件,并使用sdk.dir属性来设置SDK路径。 
另外,你也可以通过设置ANDROID_HOME环境变量,这两种方式没有什么不同,根据你自己的喜好选择其中一种设置。 
                 

3.2 Project Structure(项目结构)


上面提到的基本的构建文件需要一个默认的文件夹结构。Gradle遵循约定优先于配置的概念,在可能的情况尽可能提供合理的默认配置参数。

基本的项目开始于两个名为“source sets”的组件,即main source code和test code。它们分别位于:
    * src/main/
    * src/androidTest/

里面每一个存在的文件夹对应相应的源组件。
对于Java plugin和Android plugin来说,它们的Java源代码和资源文件路径如下:
    * java/
    * resources/

但对于Android plugin来说,它还拥有以下特有的文件和文件夹结构:
    * AndroidManifest.xml
    * res/
    * assets/
    * aidl/
    * rs/
    * jni/

注意:src/androidTest/AndroidManifest.xml是不需要的,它会自动被创建。

3.2.1 Configuring the Structure(配置项目结构)

当默认的项目结构不适用的时候,你可能需要去配置它。根据Gradle文档,重新为Java项目配置sourceSets可以使用以下方法:

sourceSets {
        main {
            java {
                srcDir 'src/java'

            }

            resources {

                srcDir 'src/resources'

            }

        }
    }

注意:srcDir将会被添加到指定的已存在的源文件夹中(这在Gradle文档中没有提到,但是实际上确实会这样执行)。 
     
替换默认的源代码文件夹,你可能想要使用能够传入一个路径数组的srcDirs来替换单一的srcDir。以下是使用调用对象的另一种不同方法: 

sourceSets {
        main.java.srcDirs = ['src/java']
        main.resources.srcDirs = ['src/resources']
    }


想要获取更多信息,可以参考Gradle文档中关于 Java Pluign的部分。 

Android Plugin使用的是类似的语法。但是由于它使用的是自己的sourceSets,这些配置将会被添加在android对象中。 
以下是一个示例,它使用了旧项目结构中的main源码,并且将androidTest sourceSet组件重新映射到tests文件夹。 

android {
        sourceSets {
            main {
                manifest.srcFile 'AndroidManifest.xml'
                java.srcDirs = ['src']

                resources.srcDirs = ['src']
                aidl.srcDirs = ['src']

                renderscript.srcDirs = ['src']

                res.srcDirs = ['res']
                assets.srcDirs = ['assets']

            }


            androidTest.setRoot('tests')
        }
    }


注意:由于旧的项目结构将所有的源文件(java,aidl,renderscripthe和java资源文件)都放在同一个目录里面,所以我们需要将这些sourceSet组件重新映射到src目录下。 
注意:setRoot()方法将移动整个组件(包括它的子文件夹)到一个新的文件夹。示例中将会移动scr/androidTest/*到tests/*下。 
以上这些是Android特有的,如果配置在Java的sourceSets里面将不会有作用。 

以上也是将旧构建系统项目迁移到新构建系统需要做的迁移工作。


3.3 Build Tasks(构建任务)


3.3.1 General Tasks(通用任务)


添加一个插件到构建文件中将会自动创建一系列构建任务(build tasks)去执行(注:gradle属于任务驱动型构建工具,它的构建过程是基于Task的)。Java plugin和Android plugin都会创建以下task:
    * assemble:这个task将会组合项目的所有输出。
    * check:这个task将会执行所有检查。
    * build:这个task将会执行assemble和check两个task的所有工作
    * clean:这个task将会清空项目的输出。
实际上assemble,check,build这三个task不做任何事情。它们只是一个Task标志,用来告诉android plugin添加实际需要执行的task去完成这些工作。

这就允许你去调用相同的task,而不需要考虑当前是什么类型的项目,或者当前项目添加了什么plugin。
例如,添加了findbugs plugin将会创建一个新的task并且让check task依赖于这个新的task。当check task被调用的时候,这个新的task将会先被调用。

在命令行环境中,你可以执行以下命令来获取更多高级别的task:

gradle tasks


查看所有task列表和它们之间的依赖关系可以执行以下命令: 

gradle tasks --all


注意:Gradle会自动监视一个task声明的所有输入和输出。 
两次执行build task并且期间项目没有任何改动,gradle将会使用UP-TO-DATE通知所有task。这意味着第二次build执行的时候不会请求任何task执行。这允许task之间互相依赖,而不会导致不需要的构建请求被执行。 

3.3.2 Java project tasks(Java项目的Task)


Java plugin主要创建了两个task,依赖于main task(一个标识性的task):
    * assemble
        * jar:
这个task创建所有输出
    * check
        * test:
这个task执行所有的测试。
jar task自身直接或者间接依赖于其他task:classes task将会被调用于编译java源码。
testClasses task用于编译测试,但是它很少被调用,因为test task依赖于它(类似于classes task)。

通常情况下,你只需要调用到assemble和check,不需要其他task。

你可以在Gradle文档中查看java plugin的全部task。

3.3.3 Android tasks


Android plugin使用相同的约定以兼容其他插件,并且附加了自己的标识性task,包括:
    * assemble:这个task用于组合项目中的所有输出。
    * check:这个task用于执行所有检查。
    * connectedCheck:这个task将会在一个指定的设备或者模拟器上执行检查,它们可以同时在所有连接的设备上执行。
    * deviceCheck:通过APIs连接远程设备来执行检查,这是在CL服务器上使用的。
    * build:这个task执行assemble和check的所有工作。
    * clean:这个task清空项目的所有输出。
这些新的标识性task是必须的,以保证能够在没有设备连接的情况下执行定期检查。
注意build task不依赖于deviceCheck或者connectedCheck。

一个Android项目至少拥有两个输出:debug APK(调试版APK)和release APK(发布版APK)。每一个输出都拥有自己的标识性task以便能够单独构建它们。
    * assemble:
        * assembleDebug
        * assembleRelease

它们都依赖于其它一些tasks以完成构建一个APK需要多个步骤。其中assemble task依赖于这两个task,所以执行assemble将会同时构建出两个APK。

小提示:gradle在命令行终端上支持骆驼命名法的task简称,例如,执行gradle aR命令等同于执行gradle assembleRelease。

check task也拥有自己的依赖:
    * check:
        * lint
    * connectedCheck:
        * connectedAndroidTest
        * connectedUiAutomatorTest(目前还没有应用到)
    * deviceCheck: 
这个test依赖于test创建时,其它实现测试扩展点的插件。

最后,只要task能够被安装(那些要求签名的task),android plugin就会为所有构建类型(debug,release,test)安装或者卸载。

3.4 Basic Build Customization(基本的构建定制)


Android plugin提供了大量DSL用于直接从构建系统定制大部分事情。

3.4.1 Manifest entries (Manifest属性)


通过SDL可以配置一下manifest选项:
    * minSdkVersion
    * targetSdkVersion
    * versionName
    * packageName
    * package Name for the test application
    * Instrumentation test runner

例如:

android {
        compileSdkVersion 19

        buildToolsVersion "19.0.0"


        defaultConfig {
            versionCode 12

            versionName "2.0"

            minSdkVersion 16
            targetSdkVersion 16
        }
    }


在android元素中的defaultConfig元素中定义所有配置。 

之前的Android Plugin版本使用packageName来配置manifest文件中的packageName属性。从0.11.0版本开始,你需要在build.gradle文件中使用applicationId来配置manifest文件中的packageName属性。 
这是为了消除应用程序的packageName(也是程序的ID)和java包名所引起的混乱。 

在构建文件中定义的强大之处在于它是动态的。 
例如,可以从一个文件中或者其它自定义的逻辑代码中读取版本信息: 

def computeVersionName() {
        ...
    }

    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.0"

        defaultConfig {
            versionCode 12
            versionName computeVersionName()
            minSdkVersion 16
            targetSdkVersion 16
        }
    }


注意:不要使用与在给定范围内的getter方法可能引起冲突的方法名。例如,在defaultConfig{...}中调用getVersionName()将会自动调用defaultConfig.getVersionName()方法,你自定义的getVersionName()方法就被取代掉了。 

如果一个属性没有使用DSL进行设置,一些默认的属性值将会被使用。以下表格是可能使用到的值:

Property NameDefault value in DSL objectDefault value
versionCode    -1value from manifest if present
versionName    null    value from manifest if present
minSdkVersion  -1value from manifest if present
targetSdkVersion  -1value from manifest if present
packageName    packageName    value from manifest if present
testPackageNamenull    app package name + “.test”
testInstrumentationRunnernull    android.test.InstrumentationTestRunner
signingConfig    null    null    
proguardFile    N/A (set only)N/A (set only)
proguardFiles    N/A (set only)N/A (set only)


如果你在构建脚本中使用自定义代码逻辑请求这些属性,那么第二列的值将非常重要。例如,你可能会写: 

if (android.defaultConfig.testInstrumentationRunner == null) {
        // assign a better default...
    }

如果这个值一直保持null,那么在构建执行期间将会实际替换成第三列的默认值。但是在DSL元素中并没有包含这个默认值,所以,你无法查询到这个值。 
除非是真的需要,这是为了预防解析应用的manifest文件。 
     

3.4.2 Build Types(构建类型)


默认情况下,Android Plugin会自动给项目设置同时构建应用程序的debug和release版本。 
两个版本之间的不同主要围绕着能否在一个安全设备上调试,以及APK如何签名。 

Debug版本采用使用通用的name/password键值对自动创建的数字证书进行签名,以防止构建过程中出现请求信息。Release版本在构建过程中没有签名,需要稍后再签名。 

这些配置通过一个BuildType对象来配置。默认情况下,这两个实例都会被创建,分别是一个debug版本和一个release版本。 

Android plugin允许像创建其他构建类型一样定制debug和release实例。这需要在buildTypes的DSL容器中配置: 

android {
        buildTypes {
            debug {
                applicationIdSuffix ".debug"

            }

            jnidebug.initWith(buildTypes.debug)
            jnidebug {
                packageNameSuffix ".jnidebug"
                jnidebugBuild true
            }
        }
    }

    
以上代码片段实现了以下功能: 
    * 配置默认的debug构建类型:将debug版本的包名设置为<app package>.debug以便能够同时在一台设备上安装debug和release版本的apk。 
    * 创建了一个名为“jnidebug”的新构建类型,并且这个构建类型是debug构建类型的一个副本。 
    * 继续配置jnidebug构建类型,允许使用JNI组件,并且也添加了不一样的包名后缀。 
     
创建一个新的构建类型就是简单的在buildType标签下添加一个新的元素,并且可以使用initWith()或者直接使用闭包来配置它。 

以下是一些可能使用到的属性和默认值:

Property nameDefault values for debugDefault values for release / other
debuggable    debuggable    false
jniDebugBuild    falsefalse
renderscriptDebugBuild  falsefalse
renderscriptOptimLevel  33
packageNameSuffix    nullnull
versionNameSuffix    nullnull
signingConfig    android.signingConfigs.debugnull
zipAlign    false    true
runProguard    falsefalse
proguardFile    N/A (set only)N/A (set only)
proguardFiles    N/A (set only)N/A (set only)



除了以上属性之外,Build Type还会受项目源码和资源影响: 
对于每一个Build Type都会自动创建一个匹配的sourceSet。默认的路径为: 

src/<buildtypename>/

这意味着BuildType名称不能是main或者androidTest(因为这两个是由plugin强制实现的),并且他们互相之间都必须是唯一的。 

跟其他sourceSet设置一样,Build Type的source set路径可以重新被定向: 

android {
        sourceSets.jnidebug.setRoot('foo/jnidebug')
    }


另外,每一个Build Type都会创建一个新的assemble<BuildTypeName>任务。 

assembleDebug和assembleRelease两个Task在上面已经提到过,这里要讲这两个Task从哪里被创建。当debug和release构建类型被预创建的时候,它们的tasks就会自动创建对应的这个两个Task。 

上面提到的build.gradle代码片段中也会实现assembleJnidebug task,并且assemble会像依赖于assembleDebug和assembleRelease一样依赖于assembleJnidebug。 

提示:你可以在终端下输入gradle aJ去运行assembleJnidebug task。 

可能会使用到的情况: 
    * release模式不需要,只有debug模式下才使用到的权限
    * 自定义的debug实现
    * 为debug模式使用不同的资源(例如当资源的值由绑定的证书决定)
 
BuildType的代码和资源通过以下方式被使用: 
    * manifest将被混合进app的manifest
    * 代码行为只是另一个资源文件夹
    * 资源将叠加到main的资源中,并替换已存在的资源。
 

3.4.3 signing configurations(签名配置)


对一个应用程序签名需要以下: 
    * 一个Keystory
    * 一个keystory密码
    * 一个key的别名
    * 一个key的密码
    * 存储类型
 
位置,键名,两个密码,还有存储类型一起形成了签名配置。 
     
默认情况下,debug被配置成使用一个debug keystory。debug keystory使用了默认的密码和默认key及默认的key密码。 
debug keystory的位置在$HOME/.android/debug.keystroe,如果对应位置不存在这个文件将会自动创建一个。 

debug构建类型会自动使用debug签名配置。 

可以创建其他配置或者自定义内建的默认配置。通过signingConfigs这个DSL容器来配置: 

android {
        signingConfigs {
            debug {
                storeFile file("debug.keystore")
            }

            myConfig {
                storeFile file("other.keystore")
                storePassword "android"
                keyAlias "androiddebugkey"
                keyPassword "android"
            }
        }

        buildTypes {
            foo {
                debuggable true
                jniDebugBuild true
                signingConfig signingConfigs.myConfig
            }
        }
    }

以上代码片段修改debug keystory的路径到项目的根目录下。在这个例子中,这将自动影响其他使用到debug构建类型的构建类型。 

这里也创建了一个新的Single Config(签名配置)和一个使用这个新签名配置的新的Build Type(构建类型)。 

注意:只有默认路径下的debug keystory不存在时会被自动创建。更改debug keystory的路径并不会自动在新路径下创建debug keystory。如果创建一个新的不同名字的SignConfig,但是使用默认的debug keystore路径来创建一个非默认的名字的SigningConing,那么还是会在默认路径下创建debug keystory。换句话说,会不会自动创建是根据keystory的路径来判断,而不是配置的名称。 

注意:虽然经常使用项目根目录的相对路径作为keystore的路径,但是也可以使用绝对路径,尽管这并不推荐(除了自动创建出来的debug keystore)。 

注意:如果你将这些文件添加到版本控制工具中,你可能不希望将密码直接写到这些文件中。下面Stack Overflow链接提供从控制台或者环境变量中获取密码的方法: 
http://stackoverflow.com/questions/18328730/how-to-create-a-release-signed-apk-file-using-gradle 
我们以后还会在这个指南中添加更多的详细信息。 

3.4.4 Running Proguard(运行 Proguard)


从Gradle Plugin for ProGuard version 4.10之后就开始支持ProGuard。ProGuard插件是自动添加进来的。如果Build Type的runProguard属性被设置为true,对应的task将会自动创建。 

android {
    buildTypes {
        release {
            runProguard true
            proguardFile getDefaultProguardFile('proguard-android.txt')
        }
    }

    productFlavors {
        flavor1 {
        }
        flavor2 {
            proguardFile 'some-other-rules.txt'
        }

    }
}


发布版本将会使用它的Build Type中声明的规则文件,product flavor(定制的产品版本)将会使用对应flavor中声明的规则文件。 

这里有两个默认的规则文件: 
    * proguard-android.txt
    * proguard-android-optimize.txt
 
这两个文件都在SDK的路径下。使用getDefaultProguardFile()可以获取这些文件的完整路径。它们除了是否要进行优化之外,其它都是相同的。 

buildTypes——安卓gradle 目录 一、前言 二、buildTypes 三、buildType 1、buildTypes存在形式 2、buildTypes 中属性的意义 3、buildTypes 中方法的意义 四、写在最后 一、前言 继 上一篇博客 分享了defaultConfig 中可配置参数的含义,今天我们来分享另一个我们也很熟悉的 buildTypes。 二、buildTypes buildTypes 也是存在于每个... 阅读详情

相关推荐

在Gradle中优雅地统一管理依赖

这篇小文章将会以上手应用的方式简单为你介绍一下如何在Gradle中使用Version Catalog优化地进行依赖统一管理

ForteScarlet's Blog 4505

Gradle和Android Gradle Plugin

目录一、下表列出每个版本的Gradle plugin所需的Gradle版本:二、什么是GradleGradle集成方式Gradle作用三、什么是Gradle pluginAndroid Gradle Plugin DSLGradle plugin集成方式 一、下表列出每个版本的Gradle plugin所需的Gradle版本: 为了能有更好的体验,我们应该尽可能使用最新版的gradle和gradle plugin。 更新Gradle点这里 Plugin version Required Gradle

开发笔记 3383

Unity打包安卓apk时遇到“build gradle project”失败的问题

Unity在打包安卓apk时经常会遇到build gradle project失败的情况,现将目前遇到的情况整理如下: 情况一:打包一会过后显示打包失败,并报如下错: 情况二:打包时一直卡在“build gradle project”,纹丝不动(在等待若干个小时后依然卡着,极少概率下可能打包成功) 导致这种情况出现的原因:网络不稳定,在下载Gradle版本或者该项目依赖的库文件时由于网络速度过慢导致下载失败,从而无法正常打包 解决办法: 1.主动更新Gradle版本: 不同的Un

啸风轩 1万+

Android Gradle - Gradle、Gradle plugin 基础认知

起由 :因为开发中build项目失败,提示了Gradle相关问题;所以在好奇心的驱使之下,抽时间好好梳理了一下Gradle方面的知识 - -~

Android、前端、小程序、后端 5864

QT窗体大小控制全攻略:从setFixedSize到事件过滤器的进阶用法

本文深入探讨了QT窗体尺寸控制的进阶实践,从基础的setFixedSize方法到结合事件过滤器实现智能动态适配。通过分析窗口状态变化、多显示器环境处理以及布局策略,提供了实现禁止缩放但支持最大化、多屏智能适配及动态约束等复杂场景的完整解决方案与核心代码示例。

weixin_29229261的博客 299

Audio2Face进阶玩法:结合LiveLink在UE5中实现MetaHuman全身动画+语音驱动(保姆级配置指南)

本文提供了一份详尽的保姆级教程,指导如何将NVIDIA Audio2Face与Unreal Engine 5的LiveLink功能结合,实现驱动MetaHuman数字人面部表情的同时,无缝融合身体动画。文章详细讲解了从环境准备、插件部署、基础面部驱动测试,到动画蓝图高级配置与多数据流融合的全流程,并分享了性能优化与问题排查的实战经验,旨在帮助创作者打造表情与肢体动作协调统一的生动数字人。

q9w8e7r6t5的博客 197

Android Gradle Plugin指南(二)——基本项目 - 琴弦第七的专栏 - 博客频道 - youkuaiyun.com

原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Basic-Project 3、Basic Project(基本项目) 一个Gradle项目的构建过程定义在build.gradle文件中,位于项目的根目录下。 3.1 Simple build files(简单的构建

OyangYujun的专栏 2329

3D Slicer5.7在win11下的源码编译安装

本博客主要参考官方安装文档以及部分优快云的博客,部分内容的书写会直接参考官方文档的内容。

Topsort的博客 4760

flutter 项目更换了电脑后 运行gradle下载问题 Android Gradle plugin requires Java 17 to run. You are currently using

adroid中配置这个,其他fluttr代码不需要修改。

初遇你时动了情 806

OWASP 2025版AI大模型攻击安全风险汇总(攻击方法种类)

提示词注入是大模型最基础、最常见的核心漏洞,攻击者通过构造直接或间接的恶意自然语言输入,篡改大模型原本的正常行为与输出结果。哪怕这类恶意内容对人类是隐藏、不可见的,只要模型能够正常解析读取,就会触发漏洞。它和大家常说的模型“越狱”相关,但并不等同:越狱是提示词注入的极端形式,会直接让模型彻底无视所有内置安全协议,完全脱离管控;而普通提示词注入,更多是针对性篡改模型行为、诱导执行特定操作。

墨痕诉清风的博客 517

论文复现《基于最大李雅普诺夫指数的电力系统暂态电压稳定评估方案》

电力系统暂态电压稳定评估方案 摘要 本研究提出了一种基于最大李雅普诺夫指数的电力系统暂态电压稳定评估方法。通过分析相空间中相邻轨迹的收敛或发散特性,该方法能够提前判别系统稳定性。论文首先阐述了暂态电压稳定机理,详细介绍了最大李雅普诺夫指数的计算方法。针对IEEE-39节点系统,建立了仿真模型并获取不同故障场景下的数据。研究开发了完整的评估程序,包括数据预处理、相空间重构、指数计算等模块,并通过与时域仿真结果的对比验证了方法的准确性。实验结果表明,该方法能够快速有效地评估电力系统的暂态电压稳定性,为系统安全运

max500600的博客 187

android 报错 This Gradle plugin requires a newer IDE able to request IDE model level 3 错误解决方案

android studio 导入项目时报错 This Gradle plugin requires a newer IDE able to request IDE model level 3 报错。 解决方法: (1): 升级android studio IDE的版本。 (2):在项目的gradle.properties配置文件中加入以下这句: gradle.properties中:...

a569503963的博客 1479

Vivado报错-4 [Routed 35-3424] SLL Assignment failed ILP VU19P

Vivado报错[Routed 35-3424] SLL Assignment failed ILP VU19P

weixin_39896700的博客 1409

解决AS编译报错:Failed to apply plugin [id com.android.application]

解决AS编译报错:Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed to apply plugin [id ‘com.android.application’] 编译Android项目时总是遇到以上报错,所以记录一下。 解决方法:添加android.overridePathCheck=true就可以了。 其实解决的方法可以在Event Log窗口中找到,如图下: 从日志第一句可以看出,应该是项目路径包

feng海涛 8万+

[Dify实战] 合同审阅助手:识别风险条款、生成修改建议-带绑定资源

摘要: Dify合同审阅助手通过AI技术提升合同审阅效率,快速识别风险条款并输出结构化修改建议。方案包括合同输入、关键条款识别、风险评级和报告生成流程,重点关注付款、责任限制等核心条款。采用分层风险分级(高/中/低)和"红线清单"机制,确保审阅标准化。实施建议先建立条款库和模板,通过样本测试优化模型,定期更新规则库。该方案可缩短审阅时间50%以上,提高风险识别准确率,最终实现法务经验的可复用沉淀。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 597

【AI智能体】基于OpenCode 搭建Skills环境与项目实战开发详解

基于OpenCode 搭建Skills环境与项目实战开发详解

congge 8899

This Gradle plugin requires a newer IDE able to request IDE model level 3

转载原博客地址 android studio&amp;nbsp; 导入项目时报错 This Gradle plugin requires a newer IDE able to request IDE model level 3 报...

shuijianbaozi的博客 373

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

还在用 AGP 3.x 的老项目?最新 Android Studio 编译报红的救命方案

经过实际测试和社区反馈,目前(2026年3月)最后一个官方还能正常编译 AGP 3.6.x / 3.5.x / 3.4.x 的 Android Studio 版本是:更新的版本(2025.1.2 后期补丁、2025.2、2026.1 等)基本都会出现 AGP 3.x 无法加载或严重报错的情况。如果你现在也遇到「打开最新 Android Studio → 老项目变红屏」的痛苦,不妨先下载救急,起码能先把开发、打包、调试跑起来。

记录技术,记录生活 900

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

上一篇: Android Gradle Plugin指南(一)——简介
下一篇: Android Gradle Plugin指南(三)——依赖关系、android库和多项目配置
spring5555
博客等级 码龄12年 7粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值