Android笔记 | Android Studio工程目录结构分析

Android Studio工程目录结构分析


我们这里以一个简单的HelloWorld工程来分析:

Android Studio工程目录

1、.gradle和.idea

    这两个目录下放置的都是Android Studio自动生成的一些文件,我们无须关心,也不要去手动编辑。

2、app

    项目中的代码、资源等内容几乎都是放置在这个目录下的,我们后面的开发工作也基本都是在这个目录下进行的,待会儿还会对这个目录单独展开进行讲解。

3、build

    这个目录你也不需要过多关心,它主要包含了一些在编译时自动生成的文件。

4、gradle

    这个目录下包含了gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle。Android Studio默认没有启动gradle wrapper的方式,如果需要打开,可以点击Android Studio导航栏 --> File --> Settings --> Build,Execution,Deployment --> Gradle,进行配置更改。

5、.gitignore

    这个文件是用来将指定的目录或文件排除在版本控制之外的。

6、build.gradle

    这是项目全局的gradle构建脚本,通常这个文件中的内容是不需要修改的。下面会详细分析gradle构建脚本中的具体内容。

7、gradle.properties

    这个文件是全局的gradle配置文件,在这里配置的属性将会影响到项目中所有的gradle编译脚本。

8、gradlew和gradlew.bat

    这两个文件是用来在命令行界面中执行gradle命令的,其中gradlew是在Linux或Mac系统中使用的,gradlew.bat是在Windows系统中使用的。

9、HelloWorld.iml

    iml文件是所有IntelliJ IDEA项目都会自动生成的一个文件(Android Studio是基于IntelliJ IDEA开发的),用于标识这是一个IntelliJ IDEA项目,我们不需要修改这个文件中的任何内容。

10、local.properties

    这个文件用于指定本机中的Android SDK路径,通常内容都是自动生成的,我们并不需要修改。除非你本机中的Android SDK位置发生了变化,那么就将这个文件中的路径改成新的位置即可。

11、settings.gradle

    这个文件用于指定项目中所有引入的模块。由于HelloWorld项目中就只有一个app模块,因此该文件中也就只引入了app这一个模块。通常情况下模块的引入都是自动完成的,需要我们手动去修改这个文件的场景可能比较少。

app目录结构

    现在整个项目的外层目录结构已经介绍完了。你会发现,除了app目录之外,大多数的文件和目录都是自动生成的,我们并不需要进行修改。想必你已经猜到了,app目录下的内容才是我们以后的工作重点,展开之后结构如下:

    那么下面我们就来对app目录下的内容进行更为详细的分析。

1、build

    这个目录和外层的build目录类似,主要也是包含了一些在编译时自动生成的文件,不过它里面的内容会更多更杂,我们不需要过多关系。

2、libs

    如果你的项目中使用到了第三方jar包,就需要把这些jar包都放在libs目录下,放在这个目录下的jar包都会被自动添加到构建路径里去。

3、AndroidTest

    此处是用来编写Android Test测试用例的,可以对项目进行一些自动化测试。

4、java

    毫无疑问,java目录是放置我们所有java代码的地方,展开该目录,你将看到我们刚才创建的HelloWorldActivity文件就在里面。

5、res

    这个目录下的内容就有点多了。简单点说,就是你在项目中使用到的所有图片,布局,字符串等资源都要存放在这个目录下。当然这个目录下还有很多子目录,图片放在drawable目录下,布局放在layout目录下,字符串放在values目录下,所以你不用担心会把整个res目录弄得乱糟糟的。

6、AndroidManifest.xml

    这是你整个Android项目的配置文件,你在程序中定义的所以四大组件都需要在这个文件里注册,另外还可以在这个文件中给应用程序添加权限声明。

7、test

    此处是用来编写Unit Test测试用例的,是对项目进行自动化测试的另一种方式。

8、.gitignore

    这个文件用于将app模块内的指定的目录或文件排除在版本控制之外,作用和外层的.gitignore文件类似。

9、app.iml

    IntelliJ IDEA项目自动生成的文件,我们不需要关心或修改这个文件中的内容。

10、build.gradle

    这是app模块的gradle构建脚本,这个文件中会指定很多项目构建相关的配置。

11、proguard-rules.pro

    这个文件用于指定项目代码的混淆规则,当代码开发完成后打成安装包文件,如果不希望代码被别人破解,通常会将代码混淆,从而让破解者难以阅读。

项目中的资源

        如果你展开res目录看一下,其实里面的东西还是挺多的,很容易让人看得眼花缭乱,如下图:

    看到这么多的文件夹也不用害怕,其实归纳一下,res目录就变得非常简单了。

所以以drawable开头的文件夹都是用来放图片的,

所有以mipmap开头的文件夹都是用来放应用图标的,

所有以values开头的文件夹都是用来放字符串、样式、颜色等配置的,

layout文件夹是用来放布局文件的。


最外层目录下的build.gradle

HelloWorld项目中有两个build.gradle文件,一个是在最外层目录下的,一个是在app目录下的。这两个文件对构建AndroidStudio项目都起到了至关重要的作用,下面我们就来对这两个文件中的内容进行详细的分析。

先来看一下最外层目录下的build.gradle文件,代码如下所示:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

// Gradle中可以使用“//”或“/**/”来添加注释,与Java类似。

// 根目录下的build.gradle用于添加子工程或模块共用的配置项。


// "buildscript"的类型为script block,而且是最上层的script block,用于配置Gradle的Project实例。其API文档为https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:buildscript(groovy.lang.Closure)

// 其余的根script block有"allprojects", "dependencies", "configurations"等,更多的可见https://docs.gradle.org/current/dsl/的“Build script structure”一节。

// Script Block是一种method的调用,传入的参数为configuration closure。执行后会对Project的属性进行配置。

// 此处的"buildscript"用于配置Project的build script的classpath。

buildscript {

// 如果需要的话,从https://jcenter.bintray.com/下载code reposities。

repositories {

jcenter()

}

// 定义classpath,gradle会从“repositories”中下载对应版本的Gradle。如果使用gradle wrapper的话,感觉这个配置会被忽略。Wrapper会自己去下载所使用的gradle版本。

dependencies {

classpath 'com.android.tools.build:gradle:2.2.2'


// NOTE: Do not place your application dependencies here; they belong

// in the individual module build.gradle files

}

}


// 该配置会被应用到所有的子工程。

allprojects {

repositories {

jcenter()

}

}


// 运行gradle clean时,执行此处定义的task。

// 该任务继承自Delete,删除根目录中的build目录。

// 相当于执行Delete.delete(rootProject.buildDir)。

// gradle使用groovy语言,调用method时可以不用加()。

task clean(type: Delete) {

delete rootProject.buildDir

}

    这些代码都是自动生成的,虽然语法结构看上去可能有点难以理解,但是如果我们忽略语法结构,只看最关键的部分,其实还是很好懂的。

首先,两处repositories的闭包中都声明了jcenter()进行配置,那么这个jcenter是什么意思呢?其实它是一个代码托管仓库,很多Android开源项目都会选择将代码托管到jcenter上,声明了这行配置之后,我们就可以在项目中轻松引用任何jcenter上的开源项目了。

    接下来,dependencies闭包中使用classpath声明了一个Gradle插件。为什么要声明这个插件呢?因为Gradle并不是专门为构建Android项目而开发的,java,c++等很多项目都可以使用Gradle来构建。因此如果我们要想使用它来构建Android项目,则需要声明com.android.tools.build:gradle:2.2.2这个插件。其中,最后面的部分是插件的版本号。

    这样我们就将最外层目录下的build.gradle文件分析完了,通常情况下你并不需要修改这个文件中的内容,除非你想添加一些全局的项目构建配置。

app目录下的的build.gradle

    下面我们再来看一下app目录下的build.gradle文件,代码如下所示:

apply plugin: 'com.android.application'


android {

compileSdkVersion 23

buildToolsVersion "23.0.3"

defaultConfig {

applicationId "com.example.helloworld"

minSdkVersion 15

targetSdkVersion 23

versionCode 1

versionName "1.0"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}

buildTypes {

release {

minifyEnabled false

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

}

}

}


dependencies {

compile fileTree(include: ['*.jar'], dir: 'libs')

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {

exclude group: 'com.android.support', module: 'support-annotations'

})

compile 'com.android.support:appcompat-v7:23.4.0'

testCompile 'junit:junit:4.12'

}

这个文件中的内容就要相对复杂一些,下面我们一行行地进行分析。首先第一行应用了一个插件,一般有两种值可选:com.android.application表示这是一个应用程序模块,com.android.library表示这是一个库模块。应用程序模块和库模块的最大区别在于,一个是可以直接运行的,一个只能作为代码库依附于别的应用程序模块来运行。

接下来是一个大的android闭包,在这个闭包中我们可以配置项目构建的各种属性。其中,compileSdkVersion用于指定项目的编译版本,这里指定成23表示使用Android 6.0系统的SDK编译。buildToolsVersion 用于指定项目构建工具的版本,目前使用的版本是23.0.3。

然后我们看到,这里在android闭包中又嵌套了一个defaultConfig闭包,defaultConfig闭包中可以对项目的更多细节进行配置。其中,applicationId 用于指定项目的包名,前面我们在创建项目的时候其实已经指定过包名了,如果你想在后面对其进行修改,那么就是在这里修改的。minSdkVersion 用于指定项目最低兼容的Android系统版本,这里指定成15表示最低兼容到Android 4.0系统。targetSdkVersion 指定的值表示你在该目标版本上已经做过了充分的测试,系统将会为你的应用程序启用一些最新的功能和特性。比如说Android 6.0系统中引入了运行时权限这个功能。而如果你将targetSdkVersion 指定成22,那么就说明你的程序最高只在Android 5.1系统上做过充分的测试,Android 6.0系统中引入的新功能自然就不会启用了。剩下的几个属性都比较简单,versionCode用于指定项目的版本号,versionName用于指定项目的版本名,这两个属性在生成安装文件的时候非常重要。

分析完了defaultConfig闭包,接下来我们看一下buildTypes闭包。buildTypes闭包中用于指定生成安装文件的相关配置,通常只会有两个子闭包,一个是debug,一个是release。debug闭包用于指定生成测试版安装文件的配置,release闭包用于指定生成正式版安装文件的配置。另外,debug闭包是可以忽略不写的,因此我们看到上面的代码中就只有一个release闭包。下面来看一下release闭包中的具体内容吧,minifyEnabled用于指定是否对项目的代码进行混淆,true 表示混淆,false 表示不混淆。proguardFiles 用于指定混淆时使用的规则文件,这里指定了两个文件,第一个proguard-android.,txt 是在Android SDK目录下的,里面是所有项目通用的混淆规则,第二个 proguard-rules.pro 是在当前项目的根目录下的,里面可以编写当前项目特有的混淆规则。需要注意的是,通过AndroidStudio直接运行项目生成的都是测试版安装文件。

这个整个android闭包中的内容就都分析完了,接下来还剩下一个dependencies闭包。这个闭包的功能非常强大,它可以指定当前项目所有的依赖关系。通常AndroidStudio项目一共有3种依赖方式:本地依赖、库依赖和远程依赖。本地依赖可以对本地的jar包或目录添加依赖关系,库依赖可以对项目中的库模块添加依赖关系,远程依赖则可以对jcenter库上的开源项目添加依赖关系。观察一下dependencies闭包中的配置,第一行的compile fileTree就是一个本地依赖声明,它表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径当中。而第三行compile 则是远程依赖声明,com.android.support:appcompat-v7:23.4.0就是一个标准的远程依赖库格式,其中com.android.support是域名部分,用于和其他公司的库做区分;appcompat-v7是组名称,用于和同一个公司中不同的库做区分;23.4.0是版本号,用于和同一个库不同的版本做区分。加上这句声明后,Gradle在构建项目时会首先检查一个本地是否已经有这个库的缓存,如果没有的话则会去自动联网下载,然后再添加到项目的构建路径当中。至于库依赖声明这里没有用到,它的基本格式是compile project后面加上要依赖的库名称,比如说有一个库模块的名字叫helper,那么添加这个库的依赖关系只需要加入compile project(':helper')这句声明即可。

深入了解三个文件

接下来我们就要剖析工程里三个比较重要的文件: MainActivity.java,布局文件:activity_main和Android配置文件:AndroidManifest.xml

1、MainActivity.java:

2、布局文件:activity_main.xml:

3、配置文件AndroidManifest.xml:

AndroidManifest文件中含有如下过滤器的Activity组件为默认启动类当程序启动时系统自动调用它

1

2

3

4

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容