gradle基础入门

1. gradle简介

Java世界中主要有三大构建工具:Ant、Maven和Gradle。经过几年的发展,Ant几乎销声匿迹、Maven也日薄西山,而Gradle的发展则如日中天。

1.1. ANT

ANT是最早的构建工具,其主要基于IDEA,在2000年的时候最流行java构建工具,虽然对工程构建过程中的过程控制特别好,也比较灵活,但是它的XML脚本编写格式让XML文件特别大。

1.2. Maven

Maven主要是用来填补Ant的坑的,Maven第一次支持了从网络上下载的功能,仍然采用xml作为配置文件格式,其主要专注的是依赖管理,主要好处是它的生命周期。虽然接连的多个项目生命周期相同,这是以灵活性为代价的。 Maven也面临着依赖管理的一些问题。它不会在同一库版本之间处理好矛盾,复杂的定制构建脚本实际上Maven比ANT更难写。

1.3. Gradle

Grale是一个自动化的构建工具,Gradle属于结合以上两个的优点,它继承了Ant的灵活和Maven的生命周期管理,它最后被google作为了Android御用管理工具。它最大的区别是不用XML作为配置文件格式,采用了DSL格式,使得脚本更加简洁。Gradle引入了基于Groovy语言的DSL语法来代替XML配置,因此它的配置文件是一个Groovy文件。

2. gradle功能特性

  • 基于声明的构建和基于约定的构建

Gradle 的核心在于基于 Groovy 的丰富而可扩展的域描述语言(DSL)。 Groovy 通过声明性的语言元素将基于声明的构建推向下层,你可以按你想要的方式进行组合。 这些元素同样也为支持 Java, Groovy,OSGi,Web 和 Scala 项目提供了基于约定的构建。 并且,这种声明性的语言是可以扩展的。你可以添加新的或增强现有的语言元素。 因此,它提供了简明、可维护和易理解的构建。

  • 为以依赖为基础的编程方式提供语言支持

声明性语言优点在于通用任务图,你可以将其充分利用在构建中. 它提供了最大限度的灵活性,以让 Gradle 适应你的特殊需求。

  • 构建结构化

Gradle 的灵活和丰富性最终能够支持在你的构建中应用通用的设计模式。 例如,它可以很容易地将你的构建拆分为多个可重用的模块,最后再进行组装,但不要强制地进行模块的拆分。 不要把原本在一起的东西强行分开(比如在你的项目结构里),从而避免让你的构建变成一场噩梦。 最后,你可以创建一个结构良好,易于维护,易于理解的构建。

  • 深度 API

Gradle 允许你在构建执行的整个生命周期,对它的核心配置及执行行为进行监视并自定义。

  • Gradle 的扩展

Gradle 有非常良好的扩展性。 从简单的单项目构建,到庞大的多项目构建,它都能显著地提升你的效率。 这才是真正的结构化构建。通过最先进的增量构建功能,它可以解决许多大型企业所面临的性能瓶颈问题。

  • 多项目构建

Gradle 对多项目构建的支持非常出色。项目依赖是首先需要考虑的问题。 我们允许你在多项目构建当中对项目依赖关系进行建模,因为它们才是你真正的问题域。 Gradle 遵守你的布局。

Gradle 提供了局部构建的功能。 如果你在构建一个单独的子项目,Gradle 也会帮你构建它所依赖的所有子项目。 你也可以选择重新构建依赖于特定子项目的子项目。 这种增量构建将使得在大型构建任务中省下大量时间。

  • 多种方式管理依赖

不同的团队喜欢用不同的方式来管理他们的外部依赖。 从 Maven 和 Ivy 的远程仓库的传递依赖管理,到本地文件系统的 jar 包或目录,Gradle 对所有的管理策略都提供了方便的支持。

  • Gradle 是第一个构建集成工具

Ant tasks 是最重要的。而更有趣的是,Ant projects 也是最重要的。 Gradle 对任意的 Ant 项目提供了深度导入,并在运行时将 Ant 目标(target)转换为原生的 Gradle 任务(task)。 你可以从 Gradle 上依赖它们(Ant targets),增强它们,甚至在你的 build.xml 上定义对 Gradle tasks 的依赖。Gradle 为属性、路径等等提供了同样的整合。

Gradle 完全支持用于发布或检索依赖的 Maven 或 Ivy 仓库。 Gradle 同样提供了一个转换器,用于将一个 Maven pom.xml 文件转换为一个 Gradle 脚本。Maven 项目的运行时导入的功能将很快会有。

  • 易于移植

Gradle 能适应你已有的任何结构。因此,你总可以在你构建项目的同一个分支当中开发你的 Gradle 构建脚本,并且它们能够并行进行。 我们通常建议编写测试,以保证生成的文件是一样的。 这种移植方式会尽可能的可靠和减少破坏性。这也是重构的最佳做法。

  • Groovy

Gradle 的构建脚本是采用 Groovy 写的,而不是用 XML。 但与其他方法不同,它并不只是展示了由一种动态语言编写的原始脚本的强大。 那样将导致维护构建变得很困难。 Gradle 的整体设计是面向被作为一门语言,而不是一个僵化的框架。 并且 Groovy 是我们允许你通过抽象的 Gradle 描述你个人的 story 的黏合剂。 Gradle 提供了一些标准通用的 story。这是我们相比其他声明性构建系统的主要特点。 我们的 Groovy 支持也不是简单的糖衣层,整个 Gradle 的 API 都是完全 groovy 化的。只有通过 Groovy才能去运用它并对它提高效率。

  • The Gradle wrapper

Gradle Wrapper 允许你在没有安装 Gradle 的机器上执行 Gradle 构建。 这一点是非常有用的。比如对一些持续集成服务来说。 它对一个开源项目保持低门槛构建也是非常有用的。 Wrapper 对企业来说也很有用,它使得对客户端计算机零配置。 它强制使用指定的版本,以减少兼容支持问题。

  • 自由和开源

Gradle 是一个开源项目,并遵循 ASL 许可。

3. gradle安装

3.1. windows安装

  • 进入gradle官网:https://gradle.org,点击【Install Gradle】
  • 进入页面后,可以看到installing manually手动安装,有binary-only和complete两种安装包,complete完整一些,包括文档和相应的源。
  • 这里我选择了binary-only下载,下载并解压到自己想要的目录,这里我解压到我的D目录:D:\
  • 添加环境变量GRADLE_HOME和path,如下所示
GRADLE_HOME:D:\F:\TEST\gradle-6.1-bin\gradle-6.1
path:%GRADLE_HOME%\bin
  • 添加环境变量完成后,打开cmd命令模式,输入gradle -v,若展示gradle基本信息,则表明安装成功

3.2. gradle目录简介

gradle的目录其实与maven的目录结构是一致的,大体如下所示:

其中:

  • build.gradle 用于配置当前项目的Gradle构建脚本
  • gradle-wrapper.jar Gradle Wrapper可执行JAR
  • gradle-wrapper.properties Gradle Wrapper配置属性
  • gradlew 基于Unix的系统的Gradle Wrapper脚本
  • gradlew.bat 适用于Windows的Gradle Wrapper脚本
  • settings.gradle 用于配置Gradle构建的Gradle设置脚本

3.3. 新建gradle项目

3.3.1. 第一种方式

直接使用命令的方式进行创建。

  • 创建一个空文件夹并进入目录
  • 依次输入如下命令:gradle init
    • 选择项目的类型
    • 选择要使用的语言
    • 选择测试框架
    • 选择脚本编写的语言
    • 输入项目名称、包名,默认是我们刚才进入的文件夹名称 ,即可。

3.3.2. 第二种方式

使用工具直接创建,在IEDA中配置gradle后创建项目。

  • File=>Settings=>Build,Execution,Deployment=>Builid Tools=>Gradle路径下配置如下:

  • 然后新建一个gradle项目
  • 然后填入指定的groupId和artifactId后完成创建,目录如下。

4. gradle构建基础

gradle构建中的两个基本概念是项目(project)和任务(task),每个构建至少包含一个项目,项目中包含一个或多个任务。在多项目构建中,一个项目可以依赖于其他项目;类似的,任务可以形成一个依赖关系图来确保他们的执行顺序。

4.1. gradle构建生命周期

Gradle的构建生命周期分为初始化,配置,执行三个阶段。

4.1.1. 初始化阶段

初始化阶段主要是读取settings.gradle 文件,用于确定哪些项目参与构建,并创建Project实例;如多个项目构建时,通常setting.gradle内容如下:

include "projectA","projectB","projectC"
//表示参与构建的项目有projectA,projectB,projectC

4.1.2. 配置阶段

配置阶段主要是为每个项目的build.gradle文件配置project对象;主要是生成task的依赖关系跟执行图。

4.1.3. 执行阶段

执行阶段主要是根据gradle命令和传入的参数创建并执行任务。

4.2. gradle任务

Gradle构建脚本描述一个或多个项目。每个项目都由不同的任务组成。任务是构建执行的一项工作,主要包括任务动作和任务依赖,任务动作定义了一个最小的工作单元,可以定义依赖,动作序列和执行条件;Gradle保证这些任务按其依赖项的顺序执行,并且每个任务只执行一次。这些任务可以抽象成一个有向无环图。Gradle会在执行任务之前构建完整的依赖关系图,这就是Gradle的核心思想。

4.2.1. 定义任务

任务是构建脚本build.gradle中的关键字,任务的定义模式大体如下所示:

task testTask{
    doLast {
        println ‘I am a tester‘
    }
}

#doLast 语句可以使用快捷方式(表示符号 <<)来简化此任务

#上述语句等同于:

task testTask << {
        println ‘I am a tester‘
}

如下,在终端中输入如下命令执行task

gradle -q testTask

4.2.2. 任务依赖

要将一个任务依赖另一个任务,在开始这个任务之前,先完成依赖的任务。 每个任务都使用任务名称进行区分。

任务的依赖第一种填写方式,我们可以直接在定义任务是指定需要依赖的任务,其中需要注意如下两点:

  • 被依赖的任务可以定义在之前或者之后
  • 如果被依赖的任务定义在之后,也叫做延迟依赖,延迟依赖下,被引用的的任务名需要加入引号,所以通常我们把引号加上就好了

task testTask  {
    doLast {
        println ‘I am a tester‘
    }
}
//被依赖的任务可以定义在之前或者之后
//如果被依赖的任务定义在之后,也叫做延迟依赖,
//延迟依赖下,被引用的的任务名需要加入引号,所以通常我们把引号加上就好了
task testDepend(dependsOn:‘testTask‘)  {
    doLast {
        println ‘I do test job‘
    }
}

如下,在终端中输入如下命令执行任务:

gradle -q testDepend

依赖的第二种填写方式,分别编写完任务后,在末尾写入依赖语句:

task testTask  {
    doLast {
        println ‘I am a tester‘
    }
}
task testDepend  {
    doLast {
        println ‘I do test job‘
    }
}
testDepend.dependsOn testTask

如下,在终端中输入如下命令执行任务:

gradle -q testDepend

4.2.3. 定位任务

如果要查找在构建文件中定义的任务,则必须使用相应的标准项目属性。这意味着每个任务都可以作为项目的属性,使用任务名称作为属性名称。

如下在build.gradle中定义了一个任务xiong,那么我们可以通过如下方式查找任务

task xiong

println xiong.name
println project.xiong.name

如下,在终端中输入如下命令执行任务:

gradle -q xiong

当然我们也可以由其任务集合(tasks)来查找。要引用另一个项目中的任务,应该使用项目路径作为相应任务名称的前缀。

task xiong
println tasks.xiong.name
println tasks[‘xiong‘].name

如下,在终端中输入如下命令执行任务:

gradle -q xiong

4.3. gradle依赖管理

Gradle构建脚本定义了构建项目的过程; 每个项目包含一些依赖项和一些发表项。依赖性意味着支持构建项目所需要的东西,比如构建时需要的jar包等。发布表示项目的结果,如测试类文件和构建文件,如war文件。

4.3.1. 依赖管理

如下是一个依赖管理简要图,其流程主要为:

  1. 依赖管理器读取到配置文件build.gradle中需要的依赖项时
  2. 先查看缓存或者本地没有指定的依赖项
  3. 如果没有,则通过网络去指定的远程仓库进行下载
  4. 下载后的依赖将保存在本地仓库
  5. 如果依赖多次使用,则会存储在依赖缓存中

传递依赖

B依赖A,如果C依赖B,那么C依赖A。

几乎所有的基于JVM的软件项目都需要依赖外部类库来重用现有的功能。自动化的依赖管理可以明确依赖的版本,可以解决因传递性依赖带来的版本冲突。

版本冲突

如下hibermate-core-3.6.3.Final.jar依赖的hibermate-core-3.2.0.Final.jar包中依赖了slf4i-api-1.5.8.jar,所以按传递依赖的性质,hibermate-core-3.6.3.Final.jar会依赖slf4i-api-1.5.8.jar

而hibermate-core-3.6.3.Final.jar本身又依赖了slf4i-api-1.6.1.jar,所以会导致版本冲突

但是因为gradle默认会依赖最高版本的jar包,所以gradle默认是不会出现版本冲突的,

4.3.2. 声明依赖关系

在gradle中,一个group、name、version确定一个唯一的jar包,如在build.gradle文件中配置如下依赖,定义了两个依赖项,一个是Hibernate core 3.6.7,第二个是Junit 4.0和更高版本。

  • Hibernate core 3.6.7用于编译时需要依赖的项
  • Junit 4.0和更高版本用于测试编译时需要依赖的项

dependencies {
    compile group: ‘org.hibernate‘, name: ‘hibernate-core‘, version: ‘3.6.7.Final‘
    testCompile group: ‘junit‘, name: ‘junit‘, version: ‘4.+‘
}

4.3.3. 依赖阶段配置

依赖关系配置只是定义了一组依赖关系,然后我们根据指定的依赖声明从Web下载外部依赖关系。如下是依赖阶段不同的标准配置:

  • compile:编译------编译项目的生产源所需的依赖关系。
  • runtime:运行时------运行时生产类所需的依赖关系。 默认情况下,还包括编译时依赖项。
  • testCompile:测试编译------编译项目测试源所需的依赖项。 默认情况下,它包括编译的产生的类和编译时的依赖。
  • testRuntime:测试运行时------运行测试所需的依赖关系。 默认情况下,它包括运行时和测试编译依赖项。

4.3.4. 外部依赖

依赖的类型有很多种,其中有一种类型称之为外部依赖。这种依赖由外部构建或者储存在不同的仓库中,例如 Maven 中央仓库或 Ivy 仓库中抑或是本地文件系统的某个目录中。

如下就定义了一个外部依赖,在进行构建时会从仓库中去查找该依赖:

dependencies {
    compile group: ‘org.hibernate‘, name: ‘hibernate-core‘, version: ‘3.6.7.Final‘
}

外部依赖包含 group,name 和 version 几个属性。根据选取仓库的不同,group 和 version 也可能是可选的。

当然,也有一种更加简洁的方式来声明外部依赖。采用:将三个属性拼接在一起即可。"group:name:version"

dependencies {
    compile ‘org.hibernate:hibernate-core:3.6.7.Final‘
}

4.3.5. 存储库配置

在添加依赖关系时, Gradle在存储库中查找它们。 存储库只是文件的集合,按group,name和version来组织构造; 默认情况下,Gradle不定义任何存储库,我们必须至少明确地定义一个存储库。如下我们先定义了一个自定义的maven仓库,然后是本地的maven仓库,最后是maven的中央仓库,在查找依赖时依次从上到下进行查找。

repositories {

//自定义maven仓库,也就是maven私服
    maven {
        url:‘xxxx‘
    }
    mavenLocal()   //本地仓库
    mavenCentral() //公共仓库-maven中央仓库

jcenter()       //公共仓库-jcenter仓库
}

4.3.6. 多项目构建

在企业项目中,包层次和类关系比较复杂,把代码拆分成模块通常是最佳实践,这选哟清晰的划分功能边界,比如把业务逻辑和数据持久化拆分开来,项目符合高内聚低耦合时,模块化就不安的很容易,这是也是多项目的由来。

4.3.7. 发布文件

依赖管理配置也被用于发布文件我们称之为打包发布或发布。

插件对于打包提供了完美的支持,所以通常而言无需特别告诉 Gradle 需要做什么。但是你需要告诉 Gradle 发布到哪里。这就需要在 uploadArchives 任务中添加一个仓库。

发布到 Maven 仓库你需要 Maven 插件的支持,当我们使用:gradle uploadArchives 命令时,Gradle 构建并上传你的 jar 包,同时产生 pom.xml 一起上传到下方指定的maven仓库。

apply plugin: ‘maven‘
uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "file://localhost/xxx/")
        }
    }
}

当我们使用:gradle uploadArchives 命令时,Gradle 便会构建并上传你的 jar 包,同时会生成一个 ivy.xml 一起上传到如下指定的ivy仓库:

uploadArchives {
    repositories {
        ivy {
            credentials {
                username "username"
                password "password"
            }
            url "http://repo.mycompany.com"
        }
    }
}

4.4. grale插件

Gradle 在它的核心中有意地提供了一些小但有用的功能,用于在真实世界中的自动化。所有有用的功能,例如以能够编译 Java 代码为例,都是通过插件进行添加的。插件都认为是被应用,通过 Project.apply() 方法来完成

4.4.1. Java插件

Java 插件向一个项目添加了 Java 编译、 测试和 bundling 的能力。它是很多其他 Gradle 插件的基础服务。

Java 插件定义了两个标准的源集,分别是 main 和 test。main 源集包含你产品的源代码,它们将被编译并组装成一个 JAR 文件。test 源集包含你的单元测试的源代码,它们将被编译并使用 JUnit 或 TestNG 来执行。

在build.grale文件中Java插件的引入如下所示:

apply plugin: ‘java‘

如上是使用短名称的方式,我们也可以使用完整的名称方式:

apply plugin: org.gradle.api.plugins.JavaPlugin

或者

apply plugin: JavaPlugin

同时Java 插件向你的项目添加了大量的任务,具体可参考官网或者地址:

https://www.w3cschool.cn/gradle/q9bp1hum.html

4.4.2. groovy插件

Groovy 的插件继承自 Java 插件并添加了对 Groovy 项目的支持。它可以处理 Groovy 代码,以及混合的 Groovy 和 Java 代码,甚至是纯 Java 代码(尽管我们不一定推荐使用)。该插件支持联合编译,可以任意地混合及匹配 Groovy 和 Java 代码各自的依赖。例如,一个 Groovy 类可以继承自一个 Java 类,而这个 Java 类也可以继承自一个 Groovy 类。这样一来,我们就能够在项目中使用最适合的语言,并且在有需要的情况下用其他的语言重写其中的任何类。

其在build.gradle文件中的添加方法如下:

apply plugin: ‘groovy‘

同样groovy插件也向Project中添加了大量的任务,具体请参考官网或者地址:

https://www.w3cschool.cn/gradle/q9bp1hum.html

4.4.3. war插件

War 的插件继承自 Java 插件并添加了对组装 web 应用程序的 WAR 文件的支持。它禁用了 Java 插件生成默认的 JAR archive,并添加了一个默认的 WAR archive 任务。

apply plugin: ‘war‘

同样war插件也向Project中添加了大量的任务,具体请参考官网或者地址:

https://www.w3cschool.cn/gradle/q9bp1hum.html

4.4.4. jetty插件

Jetty 插件继承自 War 插件,并添加一些任务,这些任务可以让你在构建时部署你的 web 应用程序到一个 Jetty 的 web 嵌入式容器中。

apply plugin: ‘jetty‘

同样jetty插件也向Project中添加了大量的任务,具体请参考官网或者地址:https://www.w3cschool.cn/gradle/xg9o1hu7.html

5. gradle构建命令


序号


命令


描述


1


gradle -q taskName1 taskName2


-q表示获取构建信息,执行具体的任务,可以指定多个任务


2


gradle tasks


列出所有任务列表


3


gradle build


Gralde 会编译并执行单元测试,并且将 src/main/* 下面 class 和资源文件打包


4


gradle build -x taskName


执行构建命令,并排除taskName任务


5


gradle build -continue


默认情况下Gradle将在任何任务失败时立即中止执行。如果我们希望即使发生故障,也可以继续执行,使用-continue


6


gradle clean


删除 build 目录以及所有构建完成的文件


7


gradle assemble


编译并打包 jar 文件,但不会执行单元测试。一些其他插件可能会增强这个任务的功能。例如,如果采用了 War 插件,这个任务便会为你的项目打出 War 包


8


grale check


编译并测试代码。一些其他插件也可能会增强这个任务的功能。例如,如果采用了 Code-quality 插件,这个任务会额外执行 Checkstyle


9


gradle -q [projectName] projects


列出所选项目及其子项目的项目层次结构


10


gradle –q [projectName] dependencies


提供所选项目的依赖关系的列表


11


gradle -q [projectName] properties


提供所选项目的属性列表


12


gradle -p projectName -x test build


多项目中指定需要构建的项目,并排除测试构建

原文地址:https://www.cnblogs.com/wendyw/p/12202356.html

时间: 2024-10-10 08:40:08

gradle基础入门的相关文章

Android基础入门教程——1.9 Android程序签名打包

Android基础入门教程--1.9 Android程序签名打包 标签(空格分隔): Android基础入门教程 本节引言: 第一章的倒数第二节,本节给大家介绍的是如何将我们的程序打包成Apk文件,并且为我们的Apk签名! 上一节中已经说了,我们后续的教程使用的IDE是Android Studio,所以本节讲解的也是AS(后面都这样 简称吧)下对项目进行打包签名! 1.什么是签名,有什么用: Android APP都需要我们用一个证书对应用进行数字签名,不然的话是无法安装到Android手机上的

android studio学习----gradle基础

Gradle是一种依赖管理工具,基于Groovy语言,面向Java应用为主,它抛弃了基于XML的各种繁琐配置,取而代之的是一种基于Groovy的内部领域特定(DSL)语言. 安装Gradle 在Android Studio系列教程一--下载与安装中新建项目成功后会下载Gradle,貌似这个过程不FQ也是可以下载,但是访问特别慢,建议FQ下载.那么下载的Gradle到什么地方呢? Mac上会默认下载到 /Users/<用户名>/.gradle/wrapper/dists 目录 Win平台会默认下

Android基础入门教程——10.12 传感器专题(3)——加速度-陀螺仪传感器

Android基础入门教程--10.12 传感器专题(3)--加速度/陀螺仪传感器 标签(空格分隔): Android基础入门教程 本节引言: 本节继续来扣Android中的传感器,本节带来的是加速度传感器(Accelerometer sensor)以及 陀螺仪传感器(Gyroscope sensor),和上一节的方向传感器一样有着x,y,z 三个轴, 还是要说一点:x,y轴的坐标要和绘图那里的x,y轴区分开来!传感器的是以左下角 为原点的!x向右,y向上!好的,带着我们的套路来学本节的传感器吧

Android基础入门教程——8.1.3 Android中的13种Drawable小结 Part 3

Android基础入门教程--8.1.3 Android中的13种Drawable小结 Part 3 标签(空格分隔): Android基础入门教程 本节引言: 本节我们来把剩下的四种Drawable也学完,他们分别是: LayerDrawable,TransitionDrawable,LevelListDrawable和StateListDrawable, 依旧贴下13种Drawable的导图: 1.LayerDrawable 层图形对象,包含一个Drawable数组,然后按照数组对应的顺序来

Android基础入门教程——8.1.2 Android中的13种Drawable小结 Part 2

Android基础入门教程--8.1.2 Android中的13种Drawable小结 Part 2 标签(空格分隔): Android基础入门教程 本节引言: 本节我们继续来学习Android中的Drawable资源,上一节我们学习了: ColorDrawable:NinePatchDrawable: ShapeDrawable:GradientDrawable!这四个Drawable~ 而本节我们继续来学习接下来的五个Drawable,他们分别是: BitmapDrawable:Insert

Android基础入门教程——2.3.12 Date &amp; Time组件(下)

Android基础入门教程--2.3.12 Date & Time组件(下) 标签(空格分隔): Android基础入门教程 本节引言: 本节我们来继续学习Android系统给我们提供的几个原生的Date & Time组件,他们分别是: DatePicker(日期选择器),TimePicker(时间选择器),CalendarView(日期视图),好吧, 其实一开始让我扣这几个玩意我是拒绝的,因为在我的印象里,他们是这样的: 简直把我丑哭了,有木有,终于知道为什么那么多人喜欢自定义这种类型的

Android基础入门教程——2.1 View与ViewGroup的概念

Android基础入门教程--2.1 View与ViewGroup的概念 标签(空格分隔): Android基础入门教程 本节引言: 告别了第一章,迎来第二章--Android中的UI(User Interface)组件的详解, 而本节我们要学习的是所有控件的父类View和ViewGroup类!突发奇想,直接翻译官方文档对 这两个东西的介绍吧,对了,天朝原因,google上不去,Android developer上不去,我们可以 改hosts或者用vpn代理,当然也可以像笔者一样使用国内的API

DAX基础入门 – 30分钟从SQL到DAX — PowerBI 利器

看到漂漂亮亮的PowerBI报表,手痒痒怎么办?! 有没有面对着稀奇古怪的DAX而感到有点丈八金刚摸不着头脑或者干瞪眼?! 有没有想得到某个值想不出来DAX怎么写而直跳脚!? 看完这篇文章,你会恍然大悟,捂脸偷笑.呼呼呼~ 前言: 这篇文章对于具有一点SQL查询基础人会十分容易理解,譬如:掌握SELECT,SUM,GROUP BY等. 注:此文不涉及到Filter Context(筛选上下文)的介绍. 正文: 对于对SQL有一定了解的人来说,咋看DAX,怎么都不习惯. 但是,如果理解以下几个后,

Linux 基础入门----推荐课程

Linux 基础入门课程:https://www.shiyanlou.com/courses/1 很好的一门Linux基础课,精炼.简洁!推荐! 课程内容: 第1节 Linux 系统简介 https://www.shiyanlou.com/courses/1/labs/1/document 第2节 基本概念及操作 https://www.shiyanlou.com/courses/1/labs/2/document 第3节 用户及文件权限管理 https://www.shiyanlou.com/