Android Studio创建JAR/AAR库

时间:2023-02-17 12:57:05

[时间:2017-09] [状态:Open]

[关键词:Android,Android Studio,gradle,jar,aar,library]

0 引言

最近在工作中遇到了升级Android Studio 2.3.3稳定版之后,无法编译jar包的问题。之后寻找AS文档-探索 Android Studio发现。可以通过AS创建和编译jar包,顺便看到支持原生开发,可以直接在AS中调试c/c++代码,这是非常不错的功能。终于可以摆脱纯打日志的开发环境了。

本系列文章也就因此而出现。我希望阅读文本文之后,大家能够基本了解如何使用新版的Android Studio开发原生引用。

这里说明一点,本文是参考谷歌的Android Studio官网来的,也可以认为是一种翻译版。可以访问的话你可以直接查看对应内容。

这是第三篇:使用Android Studio创建库文件(Java)。(严格来说这跟原生开发没什么关系,但是为了完整的完成我最初的目标,还是整理下此文吧。)

1 环境准备

请参考本系列的第一篇:原生库示例创建及验证中的要求,安装和更新Android Studio。

2 Android库简介

Android库在结构上与app module等价。它可以包含所有用于构建app的东西,包括源码、资源文件和Android manifest。Android库不是直接编译成可在设备上执行的APK文件,而是编译为AAR(Android Archive)文件,你可以将该文件作为app module的依赖项。和JAR包不同的是,AAR文件可以包含Android资源和manifest文件,这就是说除了Java类和方法之外,AAr还支持打包诸如layouts和drawables之类的共享资源。

Android库模块在以下情况下很有用:

  • 当你在构建多个使用相同组件的app时,比如Activity、service或UI layout。
  • 当你基于多个APK变种构建app时,例如免费版和付费版,他们共享同样的核心组件。

在以上了两种情况中,只要简单的把需要重用的文件放到库模块中,然后在app module中添加该库作为依赖项就可以了。本文将告诉你如何实现这些。

3 新建库模块

AS中新建一个库模块,步骤如下:

  1. 点击菜单中的 File > New > New Module
  2. 在Create New Module窗口中,选择Android Library,点击Next。
    • 这里也可以选择新建Java库,也就是构建传统的JAR包。
  3. 给你的库选择一个名字,并选择一个最低SDK版本,之后点击Finish。

    当Gradle完成工程同步,库模块就会显示在工程面板中。

4 将现在app module转为库模块

可以参考下列步骤:

  1. 打开module层的build.gradle文件

  2. 删除applicationId这一行,这个标志只能在Android app module中定义。

  3. 在该文件的开头,你应该能看到下面内容:

    apply plugin: 'com.android.application'

    将其更改为:

    apply plugin: 'com.android.library'

  4. 保存该文件,并点击菜单中的Tools > Android > Sync Project with Gradle Files。

这就搞定了。整个模块的结构是不变的,但现在它是以Android库运行的,构建时会新建一个AAR文件,而不是APK。

5 配置AAR作为依赖项

在其他app module中使用Android库时,需要按照下面方式配置:

  1. 使用以下两种方式将库添加到你的工程中(如果你在同一个工程中新建了库模块,你可以跳过此步骤):
    • 添加编译好的AAR/JAR文件(该库必须已经构建好)
      1. 点击菜单中的File > New > New Module。
      2. 点击Import .JAR/.AAR Package,并点击Next。
      3. 输入编译好的AAR/JAR文件的路径,并点击Finish。
    • 将库模块导入到你的工程(库源代码将成为你工程的一部分)
      1. 点击菜单中的File > New > Import Module.
      2. 输入库模块的目录,并点击Finish。

        The library module is copied to your project, so you can actually edit the library code. If you want to maintain a single version of the library code, then this is probably not what you want and you should instead add the compiled AAR file as described above.
  2. 检查下你的settings.gradle文件中新加入的库是否在其中,如下面所示添加了"my-library-module":

    include ':app', ':my-library-module'
  3. 打开app module的build.gradle文件,并在dependencies块中添加一行,如下代码片段所示:
    dependencies {
    compile project(":my-library-module")
    }
  4. 点击Sync Project with Gradle Files

在上面示例中,编译配置中添加了一个名为my-library-module的库作为整个app module的构建依赖项。如果你希望在特定构建变量上需要该库,不要使用compile,而是使用buildVariantNameCompile命令。例如,如果你只想在"pro"产品中包含该库,你需要这样编写:

productFlavors {
pro { ... }
}
dependencies {
proCompile project(":my-library-module")
}

通过上述设置之后,Android库中所有的代码和资源都可以在app module中访问了,在构建时,对应库的AAR文件会被打包到APK中。

如果你需要单独共享AAR文件,你可以在project-name/module-name/build/outputs/aar/中找到它,你可以通过菜单中的Build > Make Project重新构建它。

7 在库中发布非默认的variant

默认情况下,库模块仅发布和暴露"release"构建variant下的资源给其他Android工程/module。也就是说,如果app module将该库作为依赖项,即使在debug版本下的app也只能访问该库的"release"variant。然后,你可以通过在库的build.gradle文件中添加下面命令使得Gradle可以访问"debug"构建variant下的资源:

android {
...
// Sets the "debug" build variant as the default variant
// of the library that Gradle should publish.
defaultPublishConfig "debug"
}

这样配置之后,Gradle将发布"debug"构建variant下的资源。然而,如果库模块使用product flavors,你就需要配defaultPublishConfig属性,并使用全配置名来指定构建variant(否则,Gradle将不会发布你的库,因为传统的"release"及"debug" variant已经不存在了)。下面示例展示了如何组合使用 "demo" product flavor和"debug"构建类型的导出构建variant:

android {
...
defaultPublishConfig "demoDebug"
}

谨记:如果你正在构建用于发布app的release版本,你需要修改defaultPublishConfig以使用库的release variant对应的资源。同样的,你可以设置Gradle来发布和暴露库中所有可用的variant,同时每个app variant仅使用其需要variant的资源。在库的build.gradle文件中添加以下行可以让Gradle发布库中所有的variants:

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
}

现在你可以通过修改你的app的build.gradle文件的dependencies块来访问库中所有可见的variants。下面位于app module的build.gradle文件中的代码片段指示Gradle在构建app的"demoDebug"版本时使用库的"demoDebug" variant,并在构建app的"fullRelease"版本时使用"fullRelease" variant。

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')
...
}

8 选择作为public的资源

默认情况下库中所有的资源都是public的。为了将所有资源默认设置为private,你需要至少定义一个特殊属性作为public。资源包括你的工程下的res目录中的所有文件。为了阻止库的用户访问仅供内部使用的资源,你需要使用自动private设计机制,声明一个或多个public资源。同时,你可以把所有资源设置为private,只要添加一个空的<public />标签即可,这个标签主要是标记不存在public资源,也就是所有资源都是private的。

为了声明一个public资源,在库的public.xml中添加一个声明。如果你之前没有添加过public资源,你需要在res/values/目录下创建一个public.xml文件。

下面示例代码创建了两个public字符串:mylib_app_name和mylib_public_string:

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

你需要保证中那些使用你的库的开发者可以访问的资源设置为public。例如,v7 appcompat库中大多数资源是private的,但是控制Toolbar widget的属性是public的,以支持material design

隐式地将属性设置为private不仅可以防止库的用户得到内部库资源的代码自动补全提示,而且允许你在不破坏客户端的前提下重命名或删除private资源。private资源会被代码自动补全和theme editor自动过滤掉,并且Lint在你引用private资源时会给出警告信息。

在构建库时,Android Gradle插件将会获取public资源定义,并将其提取到public.txt文件中,此文件会被打包到AAR文件中。

9 开发考量

在你开发库模块和依赖库的app时,请留心以下行为和限制。

一旦在Android app module中添加了对库模块的引用,你就可以设置其相对优先级。在编译时,库模块会一个个合并到app中,按照优先级的高低顺序合并。

  • 资源合并冲突

    构建工具会将库模块的资源和其所依附的app module进行合并。如果给定的资源ID在两个module中都有定义,则使用app中的资源。

    如果在多个AAR库中发生冲突,那么在dependencies列表中第一个出现(在dependencies块的顶部)的资源会被使用。

    为了避免通用资源ID的冲突,可以考虑使用前缀或者统一命名方案,以保证每个module的名字都是唯一的(或在整个工程module中是唯一的)。
  • 库模块可以包含JAR包

    你可以开发一个本身包含JAR包的库模块;然而,你需要对依赖该库的app module进行手工编辑构建路径,并添加该JAR包所在路径。
  • 库模块可以依赖外部的JAR包

    你可以开发一个依赖外部库的库模块。(例如,Maps外部库)。在这种情况下,依赖该库的app在构建时必须使用一个包含该外部库(例如,Google API Add-on)的target。需要注意的是,在库模块和app module的manifest文件中必须声明该外部库,使用元素。
  • 库模块不能包含原始asset

    在库模块中,工具并不支持使用原始asset文件。app中使用的任何asset资源必须保存在其assets/目录下。
  • app module的minSdkVersion必须大于等于库中定义的版本。

    一个库被编译为app module的一部分,所以在库中使用的API必须与app module支持的平台版本兼容。
  • 每个库模块都可以创建单独的R类

    在你构建有库依赖的app module时,库模块首先被编译到AAR文件中,然后添加到app module中。因此,每个库都有其自己的R类,其命名是按照库的包名确定的。从主模块和库模块生成的R类在所有包中创建,这些都是会包含在主模块包中和库的包中。
  • 库模块可以包含自己的ProGuard配置文件

    你可以在库上实现代码缩减,通过在你的库中添加ProGuard配置文件,其中包含了ProGuard指令。构建工具会把这个文件嵌入到生成的AAR文件中。当你把该库添加到app module之后,库的ProGuard文件会被添加到app Module的ProGuard配置文件(proguard.txt)中。

    通过在你的库模块中嵌入一个ProGuard文件,你可以确保那些依赖于该库的app module在使用你的库是无需手动更新他们的ProGuard文件。当ProGuard在Android app module上执行时,它会自动使用来自app module和库中的指令,这样你就不用单独执行库中的配置文件了。

    为了指定你的库配置文件的名字,在consumerProguardFiles方法中添加下参数,该方法在你的库的build.gradle文件中的defaultConfig块中。例如,下面代码段将lib-proguard-rules.txt作为该库的ProGuard配置文件:
android {
defaultConfig {
consumerProguardFiles 'lib-proguard-rules.txt'
}
...
}

为了保证你的库中的ProGuard规则不会对app module中的代码缩减产生副作用,只包含那些在你的库中不工作的禁用ProGuard功能的规则。那些用于辅助开发者的规则可能会与app module或其他库有冲突,因此不可以包含类似规则。例如,你库的ProGuard文件可以指定在app module最小化时那些代码可以保留。

  • 测试库模块和测试app一样

    主要区别在于库和它的依赖项是自动作为测试APK的依赖项的。这意味着,测试APK包含了不仅仅是它自身的代码,还有库的AAR及库的依赖项。因为并不存在独立的“测试下的app”,androidTest任务仅安装(和卸载)测试APK。

    在合并多个manifest文件时,Gradle将遵循默认优先级规则,并将库的manifest依次合并到测试APK的主manifest中。

10 AAR文件剖析

AAR文件的文件扩展名是.aar,对应的Maven生成的类型也应该是aar。该文件本身是一个zip文件,包含下列必须条目:

/AndroidManifest.xml
/classes.jar
/res/
/R.txt
/public.txt

另外,AAR文件可以包含一个或多个下列可选条目:

/assets/
/libs/name.jar
/jni/abi_name/name.so (where abi_name is one of the Android supported ABIs)
/proguard.txt
/lint.jar

11 小结及后续

本文作为Android创建的第三篇,整体比较简单,内容主要是翻译部分,整理并介绍了如何使用AS构建JAR包。仅供后续参考。

Android Studio创建JAR/AAR库的更多相关文章

  1. android studio 使用jar包&comma;arr包和怎么使用githup开源项目中的aar包或module

    我这里的android studio的版本是2.2.3版本 一.现在大家都用android studio了,就有人问怎么使用jar包 其实使用jar包比较简单 直接吧jar放入工程的app目录下的li ...

  2. Android Studio创建库项目及引用

    Android Studio创建库项目其实创建的是在主项目下创建Module模块,这个Module模块创建的时候选择库项目模式. 为什么要这样处理呢?因为在Android Studio中一个WorkS ...

  3. Android Studio安卓导出aar包与Unity 3D交互

    Unity与安卓aar 包交互 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分 ...

  4. Android Studio创建Module-库模块

    Android Studio创建Module-库模块   本文链接:https://blog.csdn.net/niuba123456/article/details/81049676 模块是源文件和 ...

  5. &lbrack;转&rsqb;Android Studio创建Xposed模块项目时BridgeApi的正确添加方式

    使用Android Studio创建的空项目作为Xposed Module App,对于Api Jar包的引用方式,一开始是按照傻瓜式Jar Lib的处理方式,复制XposedBridgeApi-54 ...

  6. 【Android Studio使用教程2】Android Studio创建项目

    创建项目 首先,先指出Android Studio中的两个概念. Project 和 Module .在Android Studio中, Project 的真实含义是工作空间, Module 为一个具 ...

  7. Android Studio创建项目

    创建项目 首先,先指出Android Studio中的两个概念. Project 和 Module .在Android Studio中, Project 的真实含义是工作空间, Module 为一个具 ...

  8. (转载) Android studio如何生成aar包

    Android studio如何生成aar包 标签: Android studio如何生成aaAndroid studio aarAndroid 如何生成aar包 2016-12-21 14:42 1 ...

  9. Android Studio中导入第三方库

    之前开发Android都是使用的eclipse,近期因为和外国朋友Timothy一起开发一款应用,他是从WP平台刚切换使用Android的,使用的开发环境时Android Studio,为了便于项目的 ...

随机推荐

  1. 第六章、Struts2数据校验

    一.三种实现方式 ① 用validate()方法实现数据校验 继承ActionSupport类,该类实现了Validateable接口,该接口中定义了一个validate()方法,在自定义的Actio ...

  2. Hibernate get和load区别

    1.从返回结果上对比:load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常get方法检索不到的话会返回null   2.从检索执行机制上对比: ...

  3. sklearn 组合分类器

    组合分类器: 组合分类器有4种方法: (1)通过处理训练数据集.如baging  boosting (2)通过处理输入特征.如 Random forest (3)通过处理类标号.error_corre ...

  4. &lbrack;VS2012&rsqb;无法新建或者编译已有的项目

    今天启动VS2012时,发现提示插件错误,然后打开以前的网站时,发现报错如下: ContractNameMicrosoft.VisualStudio.Utilities.IContentTypereg ...

  5. SQLite入门与分析&lpar;三&rpar;---内核概述&lpar;1&rpar;

    写在前面:从本章开始,我们开始进入SQLite的内核.为了能更好的理解SQLite,我先从总的结构上讨论一下内核,从全局把握SQLite很重要.SQLite的内核实现不是很难,但是也不是很简单.总的来 ...

  6. 编译不通过:提示XXXX不是类或命名空间名 的解决办法

    手动写了一个类,需要引入预编译头stdafx.h.结果编译时提示XXXX不是类或命名空间名. 处理方法:将#include "stdafx.h"放在最前面.

  7. java把函数作为参数传递

    public class Tool { public void a()// /方法a { System.out.print("tool.a()..."); } public voi ...

  8. 搞懂MySQL InnoDB B&plus;树索引

    一.InnoDB索引 InnoDB支持以下几种索引: B+树索引 全文索引 哈希索引 本文将着重介绍B+树索引.其他两个全文索引和哈希索引只是做简单介绍一笔带过. 哈希索引是自适应的,也就是说这个不能 ...

  9. Codeforces389D&lpar;SummerTrainingDay01-J&rpar;

    D. Fox and Minimal path time limit per test:1 second memory limit per test:256 megabytes input:stand ...

  10. shell编程第一天

    shell编程基础 脚本:简单来说就是一条条的文字命令(一些指令的堆积)Shell属于内置的脚本 1.程序开发效率非常高,依赖于功能强大的命令可以迅速地完成开发任务(批处理) 2.语法简单,代码写起来 ...