[翻译]Android Studio - 创建 Android Library

原文:Create an Android Library
https://developer.android.com/studio/projects/android-library.html

Android library 结构上与 Android 应用模块(app module) 相同。它可以包含构建应用所必需的一切,包括源码(source code)、资源文件(resource files)和清单(Android manifest)。然而 Android library 可以被编译成 AAR(Android Archive) 文件被 Android 应用模块 依赖,却不能被编译成APK在设备上运行。

库模块(library module)在下列情况下有用:

  1. 当你创建的多个应用使用了相同组件,比如 activities、services、UI layouts。
  2. 当你创建的一个应用存在多个需要相同核心组件的APK版本,比如免费版与付费版。

这两种情况下,简单的移动你想重用的文件到一个库模块中然后添加这个库模块作为各个应用模块的依赖。本文将教你怎样做。

创建一个库模块

  1. 点击 File > New > New Module.
  2. Create New Module 窗口中,点击 Android Library,然后点击 Next
    另一选择是创建一个 Java Library ,它会构建一个传统的 JAR 文件。
    JAR 文件对许多项目有用,特别是当你想在不同的平台分享代码时,但它不能包含对 Android 项目代码重用有益的资源或清单(manifest)文件。
    所以这个指南重点在创建 Android Libraries.
  3. 给你的 Library 命名并选择一个最小的 SDK 版本,然后点击 Finish

一旦 Gradle 项目同步完成,库模块将出现在左边的 Project 面板中。如果你没看到新模块文件夹,请确保 Android view 已显示.

将 应用模块 转换成 库模块

如果你有想重用代码的应用模块,可以把它转换成一个库模块,如下所述:

  1. 打开现有应用模块的 build.gradle 文件,在顶部,你可以看到:
apply plugin:'com.android.application'
  1. 更改插件赋值为如下所示:
apply plugin:'com.android.library'
  1. 点击 Sync Project with Gradle Files.

就这样,这个模块的整个结构保持不变,但它现在是作为一个 Android library 且构建将创建一个 AAR 文件而非 APK 文件.

添加你的 Library 作为依赖

在应用模块中使用 Android Library 代码,过程如下:

  1. 将 Library 添加到项目中有2种方法(如果创建的库模块在同一个项目中,可跳过这步)
  • 添加已编译的AAR或JAR文件:

    1. 点击 File > New Module
    2. 点击 Import .JAR/.AAR Package,然后点击 Next
    3. 输入 AAR 或者 JAR 文件的位置,然后点击 Finish
  • 导入库模块到项目中:

    1. 点击 File > New > Import Module
    2. 输入库模块文件的位置,然后点击 Finish

    库模块已经复制到你的项目中,因此你能够编辑 Library 代码。如果你想保持 Library 代码的唯一版本,那么这可能不是你想要的,你应该导入编译好的 AAR 文件.

  1. 确保 Library 列在 settings.gradle 文件里,这里显示为一个名字为 "my-library-module" 的 Library:
include ':app', ':my-library-module'
  1. 打开应用模块的build.gradle文件,在dependencies块中添加如下代码:
dependencies { 
    compile project(":my-library-module") 
}
  1. 点击 Sync Project with Gradle Files

在上面这个例子中,名为my-library-module的 Android Library 模块成为build.gradle文件所在模块的构建依赖.

现在可以在你的应用模块中访问任何 Android library 的代码和资源,并且库的 AAR 文件会在构建时打包到你的 APK。

然而,如果你想单独分享你的 AAR 文件,你可以在project-name/module-name/build/outputs/aar/找到它,也可以通过点击 Build > Make Project 重新产生。

选择资源公开

库里的资源默认是公开的(public)。要让所有资源为隐式私有(private),你必须定义至少一个具体的公开属性(attribute as public)。资源包括你的项目res/目录中的所有文件,比如图像。要阻止你的库用户访问仅供内部使用的资源,你应该使用这种声明一个以上公开资源的自动化私有指定机制。

公开资源需要添加声明到你的库的public.xml文件。如果你之前没有添加过公开资源,那你需要在你的库的/res/values目录创建public.xml文件。

以下示例代码创建了两个名为 mylib_app_namemylib_public_string 的公开字符串资源:

<resources>
    <public name="mylib_app_name" type="string"/>
    <public name="mylib_public_string" type="string"/>
</resources>

任何你希望对使用你的库的开发者可见的资源都应该公开。例如,虽然 v7 appcompat library 的大部分资源都是私有的,但控制 Toolbar 组件以支持 material design 的属性是公开的。

隐式地让属性私有不仅能阻止你的库的用户感知到内部库资源(通过代码完成推荐),还允许你去重命名或移除私有资源的同时不破坏库的客户(clients of library)。私有资源可以被代码完成和 theme editor 筛选出来,Lint 会在你尝试使用私有资源时警告你。

开发者需要考虑的内容

当你开发library moduledependent apps,你应该注意到下列行为和限制:

一旦你将library module的引用添加到Android app module,就可以设置它们的优先级(relative priority)。在构建时,所有库根据优先级从低到高依次与应用合并.

  1. 资源合并冲突

构建工具合并库模块的资源到dependent app module。如果给定的资源ID在这两个模块中都有定义,使用 app 的资源。

如果冲突发生在多个 AAR library 中,则使用从依赖列表中先列出的库的资源。

为了避免相同ID资源的冲突,考虑用一个前缀或者其它一致性命名方案以在模块(或所有项目)中保持唯一。

  1. 库模块可以包含 JAR library

你可以开发包含 JAR library 的库模块,但是,你需要手动编辑 dependent app module 的构建路径,并添加 JAR 文件的路径。

  1. 库模块可以依赖外部 JAR library

你可以开发依赖外部 JAR library 的库模块(比如 Maps 库)。这种情况下,dependent app必须建立对应包含外部库的目标(比如 Google APIs Add-On)。 注意,库模块和 dependent app 必须在它们清单(manifest)文件的 <uses-library> 元素中中声明外部库。

  1. 库模块不能包括 raw assets

工具不支持在库模块中使用 raw asset 文件(保存在 assets/ 目录中)。app 使用的任意 asset 资源必须存储在自身模块的 assets/ 目录中.

  1. 应用模块的minSdkVersion必须大于或等于其在库中的定义

库被编译为 dependent app module 的一部分,所以库模块中使用的 APIs 必须与app module支持的平台版本兼容。

  1. 每个库模块都创建它自己的R类

当你建立有依赖的应用模块,库模块被编译到 AAR 文件然后被添加到应用模块。因此,每个库都有根据自身包名命名的R类。由主模块与库模块生成的R类被创建于被需要的所有模块的包,

  1. 库模块可以包含自己的 ProGuard 配置文件

你可以对库启用代码压缩,通过添加一个包含 ProGuard 指令的 ProGuard 配置文件到你的库中。构建工具将这个文件嵌入库模块生成的 AAR 文件中。当你添加库到一个应用模块,库的 ProGuard 文件将被追加到应用模块的 ProGuard 配置文件中(proguard.txt)。

将 ProGuard 文件嵌入库模块,使你能确保依赖你的库的应用模块就不需要手动更新它们的 ProGuard 文件就能使用你的库。当 Android 应用模块运行 ProGuard 时,它会同时使用应用模块与库模块的指令所以你不需要单独对库运行 ProGuard。

在你的库的 build.gradle 文件的 defaultConfig 块内使用 consumerProguardFiles 方法指定配置文件名称。例如,以下代码片段设置 lib-proguard-rules.txt 为库的 ProGuard 配置文件:

android {
    defaultConfig {
        consumerProguardFiles 'lib-proguard-rules.txt'
    }
    ...
}

默认情况下,应用模块引用库使用 release 构建,即使应用模块使用 debug 构建类型。要对库使用不同的构建类型,你必须添加依赖到应用模块 build.gradle 文件的 dependencies 块同时在库模块的 build.gradle 文件中设置 publishNonDefaulttrue 。例如,下列代码段置于应用的 build.gradle 文件中使得应用在 debug 模式构建时库使用 debug 构建类型,应用在 release 模式构建时库使用 release 构建类型:

dependencies {
    debugCompile project(path: ':library', configuration: 'debug')
    releaseCompile project(path: ':library', configuration: 'release')
}

你还须要在库的 build.gradle 文件添加下列代码,对使用它的项目暴露库的 non-release 配置:

android {
    ...
    publishNonDefault true
}

注意:publishNonDefault 会增加构建时间。

要确保你的库的 ProGuard 规则不对应用模块产生多余的压缩副作用,包含的规则需要禁用对你的库无用的 ProGuard 特性。这些规则帮助开发者处理与应用模块中现存代码的冲突。举个例子,你的库的 ProGuard 文件可以在应用模块压缩指定什么代码需要被保留

注意: Jack toolchain 仅支持 ProGuard 的压缩(shrinking)和混淆(obfuscation)选项。

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

推荐阅读更多精彩内容