Gradle入门--基本配置

Gradle配置:

Gradle构建脚本 build.gradle

Gradle属性文件 gradle.properties

Gradle设置文件 settings.gradle

build.gradle

先看整个项目的gradle配置文件:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath ‘com.android.tools.build:gradle:1.3.0‘

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

内容主要包含了两个方面:一个是声明仓库的源,这里可以看到是指明的jcenter(), 之前版本则是mavenCentral(), jcenter可以理解成是一个新的中央远程仓库,兼容maven中心仓库,而且性能更优。

另一个是声明了android gradle plugin的版本,android studio 1.0正式版必须要求支持gradle plugin 1.0的版本

某个Moudle的gradle配置文件:

buildscript

buildscript {
    repositories {
        maven { url ‘http://*********‘ }
    }

    dependencies {
        classpath ‘com.android.tools.build:gradle:1.3.1‘
    }
}
  • buildscript{}设置脚本的运行环境。
  • repositories{}支持java依赖库管理,用于项目依赖。
  • dependencies{}依赖包的定义。支持maven/ivy,远程,本地库,也支持单文件。如果前面定义了repositories{}maven 库,则使用maven的依赖库,使用时只需要按照用类似于com.android.tools.build:gradle:0.4,gradle 就会自动的往远程库下载相应的依赖。

apply

//声明引用 com.android.application 插件,那么这个模块就是一个Android应用程序
apply plugin: ‘com.android.application‘
  • apply plugin:声明引用插件的类型。如果是库的话就加
apply plugin: ‘com.android.library‘
  • apply from:表示引用其他的配置文件,比如 apply from:"config.gradle"

android

这个是 Android 插件引入的 Script blocks

android {
    // 编译SDK的版本
    compileSdkVersion 22
    // build tools的版本
    buildToolsVersion "23.0.1"

    //aapt配置
    aaptOptions {
        //不用压缩的文件
        noCompress ‘pak‘, ‘dat‘, ‘bin‘, ‘notice‘
        //打包时候要忽略的文件
        ignoreAssetsPattern "!.svn:!.git"
        //分包
        multiDexEnabled true
        //--extra-packages是为资源文件设置别名:意思是通过该应用包名+R,com.android.test1.R和com.android.test2.R都可以访问到资源
        additionalParameters ‘--extra-packages‘, ‘com.android.test1‘,‘--extra-packages‘,‘com.android.test2‘
    }

    //默认配置
    defaultConfig {
        //应用的包名
        applicationId "com.example.heqiang.androiddemo"
        minSdkVersion 21
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }

    //编译配置
    compileOptions {
        // java版本
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    //源文件目录设置
    sourceSets {
        main {
             //jni lib的位置
             jniLibs.srcDirs = jniLibs.srcDirs << ‘src/jniLibs‘
             //定义多个资源文件夹,这种情况下,两个资源文件夹具有相同优先级,即如果一个资源在两个文件夹都声明了,合并会报错。
             res.srcDirs = [‘src/main/res‘, ‘src/main/res2‘]
             //指定多个源文件目录
             java.srcDirs = [‘src/main/java‘, ‘src/main/aidl‘]
        }
    }

    //签名配置
    signingConfigs {
        debug {
            keyAlias ‘androiddebugkey‘
            keyPassword ‘android‘
            storeFile file(‘keystore/debug.keystore‘)
            storePassword ‘android‘
        }
    }

    buildTypes {
        //release版本配置
        release {
            debuggable false
            // 是否进行混淆
            minifyEnabled true
            //去除没有用到的资源文件,要求minifyEnabled为true才生效
            shrinkResources true
            // 混淆文件的位置
            proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.txt‘
            signingConfig signingConfigs.debug
            //ndk的一些相关配置,也可以放到defaultConfig里面。
            //指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,arm-v8之类的so会被过滤掉)
            ndk {
                abiFilter "armeabi"
            }
        }
        //debug版本配置
        debug {
            debuggable true
            // 是否进行混淆
            minifyEnabled false
            //去除没有用到的资源文件,要求minifyEnabled为true才生效
            shrinkResources true
            // 混淆文件的位置
            proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.txt‘
            signingConfig signingConfigs.debug
            //ndk的一些相关配置,也可以放到defaultConfig里面。
            //指定要ndk需要兼容的架构(这样其他依赖包里mips,x86,arm-v8之类的so会被过滤掉)
            ndk {
                abiFilter "armeabi"
            }
        }
    }
    // lint配置
    lintOptions {
      //移除lint检查的error
      abortOnError false
      //禁止掉某些lint检查
      disable ‘NewApi‘
    }
}

android{}设置编译android项目的参数,构建android项目的所有配置都写在这里。

除了上面写的,在android{}块中可以包含以下直接配置项:

  • productFlavors{ } 产品风格配置,ProductFlavor类型
  • testOptions{ } 测试配置,TestOptions类型
  • dexOptions{ } dex配置,DexOptions类型
  • packagingOptions{ } PackagingOptions类型
  • jacoco{ } JacocoExtension类型。 用于设定 jacoco版本
  • splits{ } Splits类型。

几点说明:

  • 文件开头apply plugin是最新gradle版本的写法,以前的写法是apply plugin: ‘android‘, 如果还是以前的写法,请改正过来。
  • minifyEnabled也是最新的语法,很早之前是runProguard,这个也需要更新下。
  • proguardFiles这部分有两段,前一部分代表系统默认的android程序的混淆文件,该文件已经包含了基本的混淆声明,免去了我们很多事,这个文件的目录在 sdk目录/tools/proguard/proguard-android.txt , 后一部分是我们项目里的自定义的混淆文件,目录就在 app/proguard-rules.txt , 如果你用Studio 1.0创建的新项目默认生成的文件名是 proguard-rules.pro , 这个名字没关系,在这个文件里你可以声明一些第三方依赖的一些混淆规则。最终混淆的结果是这两部分文件共同作用的。
  • aaptOptions更多介绍 http://blog.csdn.net/heqiangflytosky/article/details/51009123

变量的引用

比如在gradle的某个地方想使用版本号,可以使用下面的方法:

def getVersionCode() {
    int code = android.defaultConfig.versionCode
    return code
}

repositories

repositories {
    flatDir {
        //本地jar依赖包路径
        dirs ‘../../../../main/libs‘
    }
}

dependencies

dependencies {
        compile files(‘libs/android-support-v4.jar‘)
        //在flatDir.dirs下面找依赖的aar
        compile (name:‘ui‘, ext:‘aar‘)
        // 编译extras目录下的ShimmerAndroid模块
        // 使用transitive属性设置为false来排除所有的传递依赖,默认为true
        compile project(‘:extras:ShimmerAndroid‘){
            transitive = false
        }
        // 编译CommonSDK模块,但是去掉此模块中对com.android.support的依赖,防止重复依赖报错
        compile (project(‘:CommonSDK‘)) { exclude group: "com.android.support" }
        provided fileTree(dir: ‘src/android5/libs‘, include: [‘*.jar‘])
        provided ‘com.android.support:support-v4:21.0.3‘
        provided project(‘:main-host‘)
        //通用使用exclude排除support-compat模块的依赖
        compile (‘com.jakewharton:butterknife:8.5.1‘){
            exclude module: ‘support-compat‘
        }

        // gradle 3.0以后版本支持的写法
        implementation ‘com.android.support.constraint:constraint-layout:1.0.2‘
        api ‘com.android.support:design:26.1.0‘
}
  • compileprovided

    compile表示编译时提供并打包进apk。

  • implementationapi

    implementation 会将依赖隐藏在内部而不对外公开,就是说使用 implementation 的依赖不会传递。比如:一个项目中app模块依赖A模块,A模块使用 implementation 来依赖 fastjson ,那么app里面如果不添加依赖的话就不能直接引用fastjson。

    api 和以前的 compile 是一样的。

  • exclude 防止重复依赖,后面会重点介绍
  • transitive 排除所有的传递依赖,后面会重点介绍
  • include

CommonSDK模块的定义可以参考settings.gradle

其他的介绍可以参考 依赖库管理。

几点说明

  • 看到上面的两个一模一样的repositoriesdependencies了吗?他们的作用是不一样的,在buildscript里面的那个是插件初始化环境用的,用于设定插件的下载仓库,而外面的这个是设定工程依赖的一些模块和远程library的下载仓库的。

settings.gradle

这个文件是全局的项目配置文件,里面主要声明一些需要加入gradle的module。

一般在setting.gradle中主要是调用include方法,导入工程下的各个子模块。

那我们在setting.gradle里面还能写什么呢?因为setting.gradle对应的是gradle中的Settings对象,那查下Settings的文档(https://docs.gradle.org/current/dsl/org.gradle.api.initialization.Settings.html),看下它都有哪些方法,哪些属性,就知道在setting.gradle能写什么了;

include ‘:AndroidDemo‘

include ‘:CommonSDK‘
project(‘:CommonSDK‘).projectDir = new File(settingsDir, ‘../../CommonSDK/‘)

include调用后,生成了一个名为:CommonSDKProject对象,project(‘:CommonSDK‘)取出这个对象,设置ProjectprojectDir属性。projectDir哪里来的?请看Project类的文档。

gradle.properties

可以在 gradle.properties 文件中配置一些变量,这些变量在这个工程下的所有module的build.gradle文件里都可以使用。这样就可以把一些共用的变量放到这里,这样后面修改的时候就可以只修改这个变量,不用各个模块都要修改了。

比如我们在 gradle.properties SDK 版本以及应用的版本号:

MIN_SDK_VERSION=21
TARGET_SDK_VERSION=22
VERSION_CODE=200100
VERSION_NAME=2.1.0
RX_ANDROID_VERSION=1.2.0

那么在 build.gradle 中可以通过project进行获取或者 "${RX_ANDROID_VERSION}" 引用:

    defaultConfig {
        applicationId "com.example.heqiang.testsomething"
        minSdkVersion project.MIN_SDK_VERSION as int
        targetSdkVersion project.TARGET_SDK_VERSION as int
        versionCode project.VERSION_CODE as int
        versionName project.VERSION_NAME
        /*
        * as int 关键字是用来进行类型转换的,因为从配置里面读取出来的默认是字符串
        *还可以使用 versionCode Integer.parseInt(project.VERSION_CODE)
        * */
    }
// 还可以这样用
dependencies {
    compile "io.reactivex:rxandroid:${RX_ANDROID_VERSION}"
    compile "io.reactivex:rxjava:${RX_JAVA_VERSION}"
}    

或者在 gradle.properties 中添加:

systemProp.versionName=1.0.0
systemProp.versionCode=100

可以通过 System.properties进行引用:

def code = System.properties[‘versionCode‘]
def name = System.properties[‘versionName‘]

调试

我们在进行一些配置的时候可能需要知道一些变量的值,这时候可以在 build.gradle 中添加打印进行调试,比如:

    defaultConfig {
        applicationId "com.example.hq.testsomething"
        minSdkVersion project.MIN_SDK_VERSION as int
        targetSdkVersion project.TARGET_SDK_VERSION as int
        versionCode project.VERSION_CODE as int
        versionName project.VERSION_NAME

        println(‘** build versionName=‘ + versionName)
    }

在 Gradle Console 中就可以看到打印:

** build versionName=2.1.0

依赖库管理

本地依赖

dependencies {
    //单文件依赖
        compile files(‘libs/android-support-v4.jar‘)
    //某个文件夹下面全部依赖
        compile fileTree(dir: ‘src/android6/libs‘, include: [‘*.jar‘])
        compile (name:‘ui‘, ext:‘aar‘)
    compile (project(‘:CommonSDK‘)) { exclude group: "com.android.support" }
        provided fileTree(dir: ‘src/android5/libs‘, include: [‘*.jar‘])
        provided ‘com.android.support:support-v4:21.0.3‘
        provided project(‘:main-host‘)
}

远程依赖

gradle同时支持mavenivy,以maven作为例子:

repositories {
 //从中央库里面获取依赖
 mavenCentral()
 //或者使用指定的本地maven 库
 maven{
  url "file://F:/githubrepo/releases"
 }
 //或者使用指定的远程maven库
 maven{
  url "https://github.com/youxiachai/youxiachai-mvn-repo/raw/master/releases"
 }
} 

dependencies {
 //应用格式: packageName:artifactId:version
 compile ‘com.google.android:support-v4:r13‘
}

项目依赖

对于项目依赖android library的话,在这里需要使用gradle mulit project机制。

Mulit project设置是gradle约定的一种格式,如果需要编译某个项目之前,要先编译另外一个项目的时候,就需要用到。结构如下(来自于官方文档):

MyProject/
| settings.gradle
 + app/
| build.gradle
 + libraries/
  + lib1/
   | build.gradle
  + lib2/
   | build.gradle

需要在workplace目录下面创建settings.gradle 的文件,然后在里面写上:

include ‘:app‘, ‘:libraries:lib1‘, ‘:libraries:lib2‘ 

例如:

include ‘:AndroidDemo‘

include ‘:CommonSDK‘
project(‘:CommonSDK‘).projectDir = new File(settingsDir, ‘../../CommonSDK/‘)

如此,gradle mutil project 就设置完毕。

对于app project如果需要应用libraries目录下的lib1,只需要在app project的build.gradle文件里的依赖中这么写:

compile project(‘:libraries:lib1‘)

类似前面的

provided project(‘:main-host‘)

即可完成,写完以后可以用gradle dependencies可以检查依赖状况

Gradle依赖的统一管理

我们可以在项目的根目录创建一个gradle配置文件config.gradle,内容如下:

ext{
    android=[
            compileSdkVersion: 22,
            buildToolsVersion: "23.0.1",
            minSdkVersion: 21,
            targetSdkVersion: 22,
            versionCode: 1,
            versionName: "1.0"
    ]
    dependencies=[
            compile:‘com.android.support:support-v4:21.0.3‘,
            compile: (project(‘:CommonSDK‘)) { exclude group: "com.android.support" },
            provided: fileTree(dir: ‘src/android5/libs‘, include: [‘*.jar‘]),
            provided: project(‘:main-host‘)
    ]
}

targetSdkVersion的版本还有依赖库的版本升级都在这里进行统一管理,所有的module以及主项目都从这里同意读取就可以了。

在build.gradle文件中加入:

apply from:"config.gradle"

意思是所有的子项目或者所有的modules都可以从这个配置文件中读取内容。

android节点读取ext中android对应项,dependencies读取dependencies对应项,如果配置有变化就可以只在config.gradle中修改,是不是很方便进行配置的管理呢?

检查依赖报告

运行命令./gradlew <projectname>:dependencies --configuration compile (projectname为settings.gradle里面配置的各个project,如果没有配置,直接运行./gradlew dependencies --configuration compile),会把依赖树会打印出来,依赖树显示了你 build 脚本声明的顶级依赖和它们的传递依赖:

仔细观察你会发现有些传递依赖标注了*号,表示这个依赖被忽略了,这是因为其他顶级依赖中也依赖了这个传递的依赖,Gradle会自动分析下载最合适的依赖。

排除传递依赖

Gradle允许你完全控制传递依赖,你可以选择排除全部的传递依赖也可以排除指定的依赖。

  • exclude:前面已经介绍过,可以设置不编译指定的模块,排除指定模块的依赖。后的参数有groupmodule,可以分别单独使用,会排除所有匹配项。
        // 编译CommonSDK模块,但是去掉此模块中对com.android.support的依赖,防止重复依赖报错
        compile (project(‘:CommonSDK‘)) { exclude group: "com.android.support" }
        compile (‘com.jakewharton:butterknife:8.5.1‘){
            exclude module: ‘support-compat‘
            exclude group: ‘com.android.**.***‘, module: ‘***-***‘
        }
  • transitive:前面已经介绍过,用于自动处理子依赖项,默认为true,gradle自动添加子依赖项。设置为false排除所有的传递依赖,可以用来解决一些依赖冲突的问题,比如一些 Error:java.io.IOException: Duplicate zip entry 报错。
        // 使用transitive属性设置为false来排除所有的传递依赖
        compile project(‘:extras:ShimmerAndroid‘){
            transitive = false
        }
  • force:强制设置某个模块的版本。
    configurations.all{
        resolutionStrategy{
            force‘org.hamcrest:hamcrest-core:1.3‘
        }
    }

这样,应用中对org.hamcrest:hamcrest-core 依赖就会变成1.3版本。

动态版本声明

如果你想使用一个依赖的最新版本,你可以使用latest.integration,比如声明 Cargo Ant tasks的最新版本,你可以这样写org.codehaus .cargo:cargo-ant:latest-integration,你也可以用一个+号来动态的声明:

dependencies {
    //依赖最新的1.x版本
    compile "org.codehaus.cargo:cargo-ant:1.+"
}

然后在依赖树里面可以清晰的看到选择了哪个版本:

\--- org.codehaus.cargo:cargo-ant:1.+ -> 1.3.1

http://www.open-open.com/lib/view/open1431391503529.html

http://www.jianshu.com/p/429733dbbc34

多渠道打包:

主要借助

android {
    productFlavors{
    ……
    }
}

来实现。

网上多是类似友盟的配置,copy过来:

http://blog.csdn.net/maosidiaoxian/article/details/42000913

https://segmentfault.com/a/1190000004050697

AndroidManifest.xml里面写上:

<meta-data
    android:name="UMENG_CHANNEL"
    android:value="Channel_ID" />

里面的Channel_ID就是渠道标示。我们的目标就是在编译的时候这个值能够自动变化。

android {
    productFlavors {
        xiaomi {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
        }
        _360 {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
        }
        baidu {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
        }
        wandoujia {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
        }
    }
}

或者批量修改

android {
    productFlavors {
        xiaomi {}
        _360 {}
        baidu {}
        wandoujia {}
    }  

    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }
}

然后用 ./gradlew assembleRelease 这条命令会把Product Flavor下的所有渠道的Release版本都打出来。

assemble<Product Flavor Name>: 允许构建指定flavor的所有APK,例如assembleFlavor1将会构建Flavor1DebugFlavor1Release两个Variant版本。

在上面当中,我们也可以指定一个默认的渠道名,如果需要的话。指定默认的值是在defaultConfig节点当中添加如下内容:

manifestPlaceholders = [ CHANNEL_NAME:"Unspecified"]  

这里的Unspecified换成你实际上的默认的渠道名。

使用manifestPlaceholders的这种配置,同样适用于manifest的其他配置。比如你需要在不同渠道发布的apk里面,指定不同的启动Activity。比如在豌豆荚里面发布的,启动的Activity显示的是豌豆荚首发的界面,应用宝里面启动的是应用宝首发的界面(哈哈,有点坏),你就可以对你的activity的值使用 {activity_name}的方式,然后在productFlavors里面配置这个{activity_name}的值。

另外这里记录一个 productFlavors 和 applicationId 关系的小知识。

参考文档

每个 Android 应用均有一个唯一的应用 ID,我们可以在通过 productFlavors 构建的应用变体中配置不同的应用 ID。

android {
    defaultConfig {
        applicationId "com.example.myapp"
    }
    productFlavors {
        free {
            applicationIdSuffix ".free"
        }
        pro {
            applicationIdSuffix ".pro"
        }
    }
}

这样,“免费”的 applicationId 就变为“com.example.myapp.free”。

原文地址:https://www.cnblogs.com/soul-wonder/p/8951817.html

时间: 2024-08-10 19:10:26

Gradle入门--基本配置的相关文章

项目自动化建构工具gradle 入门5——在intellij中做一个gradle的web工程

之前的几个小节,都是纯手工建文件夹,纯手工拷贝war包,或者纯手工解压个zip看看结果,,,,这还是我写了玩的helloWorld.若是玩大工程.几十个人的团队协同开发时,这么玩,,,,暴躁的程序员估计血压爆表了. 对于大点的java web项目,我们需要用到Tomcat 9.0 M10,gradle 3.2.1,IntelliJ 来搞定这一档子事. 1.软件下载安装,见<项目自动化建构工具gradle 入门0--环境 & 废话>. 2.打开IntelliJ,File -> Ne

Gradle入门:创建二进制发布版本

在创建了一个实用的应用程序之后,我们可能想将其与他人分享.其中一种方式就是创建一个可以从网站上下载的二进制文件. 这篇教程描述了如何创建一个二进制发布版本,满足以下需求: 二进制发布一定不能使用所谓的“fat jar”方式.换句话说,我们应用程序中的所有依赖一定不能被打包到该程序相同的jar包中. 二进制发布必须包含针对*nix和Windows操作系统的启动副本. 二进制发布的根目录必须包含许可证. 我们开始吧. 创建二进制发布文件 Application插件是一种Gradle插件,让我们可以运

【安卓笔记】gradle入门

随着Android Studio越来越完善,更多的开发者舍弃掉Eclipse.但是新的IDE与以往的Eclipse有很大区别,这导致部分开发者望而却步,其中一个大家觉得比较麻烦的是Android Studio采用的新的构建系统,gradle.那么这篇文章我将对gradle进行一个简单介绍(主要讲gradle配合Android Studio的使用),希望帮助大家熟悉gradle. 一. gradle是什么? gradle跟ant/maven一样,是一种依赖管理/自动化构建工具.但是跟ant/mav

GoLang入门-安装-配置

Go的三种安装方式 Go有多种安装方式,你可以选择自己喜欢的.这里我们介绍三种最常见的安装方式: Go源码安装:这是一种标准的软件安装方式.对于经常使用Unix类系统的用户,尤其对于开发者来说,从源码安装是最方便而熟悉的.Go标准包安装:Go提供了方便的安装包,支持Windows.Linux.Mac等系统.这种方式适合初学者,可根据自己的系统位数下载好相应的安装包,一路next就可以轻松安装了.第三方工具安装:目前有很多方便的第三方软件包工具,例如Ubuntu的apt-get.Mac的homeb

项目自动化建构工具gradle 入门4——javaWeb在浏览器中显示helloWorld

在java应用中,其实做的最多的还是java web应用.所以现在我们做的就是用gradle构建一个简单的web项目,简单点,直接上代码吧. 1.进入目录D:\work\gradle\web,新建文件build.gradle,键入内容: 1 apply plugin: 'war' // 引入war插件, 2 3 repositories { // 从哪里找jar包 4 flatDir { 5 // 先看下build.gradle文件所在目录下的 libs目录中有没有 6 dirs 'libs'

Unreal4 入门(配置)

这次主要是简单介绍下Unreal4引擎使用前的配置 和 VisualStudio2013调试插件的配置 1. 在Unreal4安装目录下找到路径为 Unreal Engine\4.0\Engine\Extras 的文件夹.如下图: 入门(配置)" alt="Unreal4 入门(配置)" src="http://s1.sinaimg.cn/mw690/002hdocVzy6I18joTnO50&690"> 可以很清晰的看到有 Android

Android studio下gradle Robolectric单元测试配置

android studio下gradle Robolectric单元测试配置 1.Robolectric Robolectric是一个基于junit之上的单元测试框架.它并不依赖于Android提供的测试功能,它使用了shadow objects并且运行测试于普通的工作站/服务器JVM,不像模拟器或设备需要dexing(Android dex编译器将类文件编译成Android设备上的Dalvik VM使用的格式),打包,部署和运行的过程,大大减少了测试执行的时间. 参考:安卓单元测试相关概述h

Gradle 入门

目录 start Gradle 书籍 发行版本列表 安装配置 SDKMAN方式 Chocolate 命令行选项 守护进程 Docker安装 配置镜像源 关键配置文件 build.gradle 初始化一个新项目 dependency 统一依赖管理 配置Wrapper 插件 常用插件 setting.gradle Gradle多模块的构建 另一种方式 部署 War包 Jar包 上传至构建仓库 构建Docker镜像 第二种插件方式 目录 end |2018-08-03| 码云 | CSDN | OSC

zabbix入门之配置邮件告警

zabbix入门之配置邮件告警 邮件环境搭建 使用本地邮箱账号发送邮件 zabbix-server 端安装 mailx .sendmail或者psotfix 服务,系统默认安装好了postfix #安装sendmail,并加入开机自启. yum -y install sendmail systemctl start sendmail systemctl enable sendmail #开启postfix并加入开机自启. systemctl start postfix systemctl ena