Android Studio User Guide

开发工作流

18:21:56.jpg

创建Android Library

一个Android Library和普通的Android工程一样都包含source code、resource、manifest文件等,但它并不编译进apk,而是编译成一个aar文件,你可以对它进行依赖。

如何创建

可以直接通过Android Studio的New Module来进行创建一个新的Module.它和普通的application的主要差别在与所依赖的Gradle Android插件。application下面的是apply plugin: 'com.android.application' 而Moudle下的是apply plugin: 'com.android.library',因此你也通过更改这个还完成相互的转换。

添加Library依赖

  1. 添加Library到project目录下

    • 可以通过new Moudle
    • import Moudle
  2. 看项目根目录下的setting。gradle是否包含该Moudle

    1
    include ':app', ':mylibrary'
  3. 在主app下的build.gradle设置对其的依赖,如果不设置则不会生效

    1
    2
    3
    dependencies {
    compile project(":mylibrary")
    }

4.进行同步

通过上面的步骤就可以使一个项目依赖一个Library了,如果只想让其在指定的build variant,可以用build variant的名字加Compile来取代compile,例如下面的就可以只在release环境下依赖mylibrary moudle:

1
releaseCompile project(":mylibrary")

对Library进行依赖后,你就有可以访问该Library下的的code和resources,在build的时候会被一起装到apk,同时你也可以在project-name/module-name/build/outputs/aar/里找到生成的aar包,也可以通过Build > Make Project重新生成。

发布Library以非默认的variants

默认的,library最终只以release的方式在Android项目里引用,即使你指定它的BuildVariant,但是我们通过添加标识来指定默认的发布方式:

1
2
3
4
5
6
android {
...
// Sets the "debug" build variant as the default variant
// of the library that Gradle should publish.
defaultPublishConfig "debug"
}

如果包含了flavors,你就必须指定它的完整的名字,例如。

1
2
3
4
android {
...
defaultPublishConfig "demoDebug"
}

在发布release时,你需要针对不同的build varients改变defaultPublishConfig,很麻烦,所以你可以告诉gradle,去生成一个Library所有的build varients,然后指定就可以了:如下:

1
2
3
4
5
6
7
android {
...
// Tells Gradle to build all variants of the library. Note that this
// may increase build times because Gradle must build multiple AARs,
// instead of only one.
publishNonDefault true
}

指定当执行demoDebug时,Library也用demoDebug

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
android {...}
...
// Creates Gradle dependency configurations to use in the dependencies block.
configurations {
// Initializes placeholder configurations that the Android plugin can use when targeting
// the corresponding variant of the app.
demoDebugCompile {}
fullReleaseCompile {}
...
}
dependencies {
// If the library configures multiple build variants using product flavors,
// you must target one of the library's variants using its full configuration name.
demoDebugCompile project(path: ':my-library-module', configuration: 'demoDebug')
fullReleaseCompile project(path: ':my-library-module', configuration: 'fullRelease')
...
}

开发考虑

当Library添加到app中时,Library集会按照一次一个的形式与应用合并,具体的规则如下:

  • 资源合并冲突
    • 当Library和app中同时存在相同的资源id时,使用app的
    • 当两个aar包存在冲突时用dependencies块中靠前的
    • 为了避免资源冲突可以根据module给资源id添加独一无二的前缀,
  • library module可以包含jar包
    • 你可以开发一个带有Jar包的Library module,但是你需要手动的在app moudle的buld path中添加这jar包的path
  • Library modules不能包含原始assets
    • 在library module中不支持使用asset文件(保存在assets目录下的),任何asset资源必须放在app module下
  • app module下的minSdkVersion必须大于等于 library下的
    因为library最后会被编译进app module,所以library module必须能够兼容app module的minSdkVersion
  • 每个library都会创建自己的R类文件
    • 在您构建相关应用模块时,库模块将先编译到 AAR 文件中,然后再添加到应用模块中。因此,每个库都有其自己的 R 类,并根据library的package命名。主要在build/generated/source
  • 当app moudle依赖了两个相同的library,但是不同版本,优先依赖高版本
  • 两个library都依赖了相同的一个库,但是库的版本不同,优先依赖高版本的,可以通过gradle dependencies查看被更改的
  • 可以在Library中添加相应的Proguard配置文件来启动代码压缩,build工具会将这个文件嵌入到library moudle生成的aar包中,当你添加library到app中,library的proguard文件会附加到app的proguard文件后面。
    当Proguard在app模块中运行时,它会执行app下的和library下的命令,所以你不需要独自在library下运行proguard。要指定您的库的配置文件名称,请将其添加到 consumerProguardFiles 方法中,此方法位于您的library的 build.gradle 文件的 defaultConfig 块内。例如,以下片段会将 lib-proguard-rules.txt 设置为库的 ProGuard 配置文件:
    1
    2
    3
    4
    5
    6
    android {
    defaultConfig {
    consumerProguardFiles 'lib-proguard-rules.txt'
    }
    ...
    }

AAR文件详解

AAR( Android Archive )文件的文件扩展名为,文件本身是一个包含以下强制性条目的 zip 文件:

  • /AndroidManifest.xml
  • /classes.jar
  • /res/
  • /R.txt
    此外,AAR 文件可能包含以下可选条目中的一个或多个:

  • /assets/

  • /libs/name.jar
  • /jni/abi_name/name.so(其中 abi_name 是 Android 支持的 ABI 之一)
  • /proguard.txt
  • /lint.jar

编写应用

改变resource 目录

默认的resource在 module-name/src/source-set-name/res/目录下,一般是src/main/res,但是可以通过gradle来设置

1
2
3
4
5
6
7
8
9
10
android {
sourceSets {
main {
res.srcDirs = ['resources/main']
}
debug {
res.srcDirs = ['resources/debug']
}
}
}

或者为一个source set指定多个资源目录

1
2
3
4
5
6
7
android {
sourceSets {
main {
res.srcDirs = ['res1', 'res2']
}
}
}

在最终的apk文件中包含以下目录下的resource文件:

  • main source set
  • Build variant source set
  • Android libraries(AARs)

如果一个resource包含多个,但只有一个被包含进最终的APK,build工具按照如下优先级选择:
build variant > build type > product flavor > main source set > library dependencies

Lint检查

从命令行构建app

gradle wrapper

主要通过gradle来进行构建,AS中会为每个项目配置一个gradle wrapper,针对windows提供了相应的.bat文件,针对linux和mac os提供了shell脚本,它们会自动下载在gradle-wrapper.properties中指定的版本。这样一来我们就不必考虑操作系统因素,直接通过wrapper执行gradle task

执行gradle task

切到项目的根目录下,执行./gradlew task-name,也可以下载gradle为其设置环境变量,然后通过gradle task-name来执行,可以通过gradle tasks看项目里的task列表.

build type

默认情况下,存在两个Build type: release 和 debug,其中debug并不会在gradle文件里显示,但其实是存在的,我们点击AS的Build Variants时会看见,平时开发时默认的就是这个模式,而且它的debuggable是为true的。无论哪种build都需要通过密钥进行sign,才能安装到手机上,debug build通过SDK tools提供的debug key,这个key是不安全的而且不能在google store上发布APK,在release buildd则需要自己的key