project生成aar文件并且在另一个project中使用遇到的坑和解决方案

前言

最近公司要一个项目的代码合并到另一个项目中,本来很简单使用import module就可以完成的,但是导入module的时候发现导入不了,原因是另一个项目中还依赖了其他的项目,直接到module肯定是不行了,于是就考虑使用导入aar的方式来解决。

1.生成aar文件

步骤1
打开需要生产aar文件的project找到app下的build.gradle文件,然后将build.gradle文件首部的apply plugin: 'com.android.application'换成apply plugin: ‘com.android.library’,
步骤2
删除掉当前build.gradle文件中的applicationId "com.example.admin.myaardemo"
步骤3
点击 Sync Project with Gradle Files也就是如下图所示的按钮
这里写图片描述
完成上面的步骤后,就可以在app的build的outputs目录下找到.aar文件了。

这里写图片描述

2.项目中导入aar文件

生产aar文件后,我们要在另一个项目中导入相应的aar文件,步骤很简单。在要导入aar文件的项目中进行下面三步操作。
步骤1
点击 File > New Module。
步骤2
依次点击 Import .JAR/.AAR Package 和 Next。
步骤3
输入 AAR 文件的位置,然后点击 Finish。

3.项目中添加对aar的依赖

导入了aar到项目中后要使用aar中的类或者方法还必须添加依赖,添加依赖很简单打开project下的setting.build文件在首部加上我们的aar文件名,比如说我们的aar名称为my-library-module.aar在setting.build如下添加。

include ':app', ':my-library-module'

打开app的 build.gradle 文件,并向 dependencies 块中添加一行新代码,如下所示:

dependencies {
compile project(“:my-library-module”)
}

4.异常处理

异常1minSdkVersion 18 cannot be smaller than version 19 declared in library
这个异常表示我们项目的minSdkVersion版本不能比aar中的minSdkVersion的版本号小,在我们项目中找到minSdkVersion将版本改为比aar中的大就行。
异常2
这里写图片描述

解决方法是将生产aar项目中的AndroidManifest.xml中相关的theme主题等有冲突的进行删除。然后重新打aar包就可以了。
异常3no resource identifier found for attribute ' in package 'com.app…

这个是xml文件的问题,找到相应的xml文件将xml文件中的xmlns:app="http://schemas.android.com/apk/res-auto"用xmlns:app=”http://schemas.android.com/apk/lib-auto”替换就行了。

5.其他问题

1.资源合并冲突

构建工具会将库模块中的资源与相关应用模块的资源合并。如果在两个模块中均定义了给定资源 ID,将使用应用中的资源。

如果多个 AAR 库之间发生冲突,将使用依赖项列表首先列出(位于 dependencies 块顶部)的库中的资源。

为了避免常用资源 ID 的资源冲突,请使用在模块(或在所有项目模块)中具有唯一性的前缀或其他一致的命名方案。

2.库模块可以包含 JAR 库

您可以开发一个自身包含 JAR 库的库模块;不过,您需要手动编辑相关应用模块的构建路径,并添加 JAR 文件的路径。

库模块可以依赖外部 JAR 库

您可以开发一个依赖于外部库(例如 Maps 外部库)的库模块。在这种情况下,相关应用必须针对包含外部库(例如 Google API 插件)的目标构建。另外也要注意,库模块和相关应用都必须在其清单文件的 元素中声明外部库。

3.库模块不得包含原始资源

工具不支持在库模块中使用原始资源文件(保存在 assets/ 目录中)。应用使用的任何原始资源都必须存储在应用模块自身的 assets/ 目录中。

应用模块的 minSdkVersion 必须大于或等于库定义的版本

库作为相关应用模块的一部分编译,因此,库模块中使用的 API 必须与应用模块支持的平台版本兼容。

4.每个库模块都会创建自己的 R 类

在您构建相关应用模块时,库模块将先编译到 AAR 文件中,然后再添加到应用模块中。因此,每个库都有其自己的 R 类,并根据库的软件包名称命名。从主模块和库模块生成的 R 类会在所需的所有软件包(包括主模块的软件包和库的软件包)中创建。

5.库模块可能包含自己的 ProGuard 配置文件

通过将 ProGuard 配置文件添加到包含其 ProGuard 指令的库,您可以在自己的库上启用代码压缩。构建工具会为库模块将此文件嵌入到生成的 AAR 文件中。在您将库添加到应用模块时,库的 ProGuard 文件将附加至应用模块的 ProGuard 配置文件 (proguard.txt)。

通过将 ProGuard 文件嵌入到您的库模块中,您可以确保依赖于此库的应用模块不必手动更新其 ProGuard 文件即可使用库。当 ProGuard 在 Android 应用模块上运行时,它会同时使用来自应用模块和库的指令,因此您不应当只在库上运行 ProGuard。

要指定您的库的配置文件名称,请将其添加到 consumerProguardFiles 方法中,此方法位于您的库的 build.gradle 文件的 defaultConfig 块内。例如,以下片段会将 lib-proguard-rules.txt 设置为库的 ProGuard 配置

android {
defaultConfig {

    consumerProguardFiles 'lib-proguard-rules.txt'
}

}
况下,应用模块会使用库的发布构建,即使在使用应用模块的调试构建类型时亦是如此。要使用库中不同的构建类型,您必须将依赖项添加到应用的 build.gradle 文件的 dependencies 块中,并在库的 build.gradle 文件中将 publishNonDefault 设置为 true。例如,应用的 build.gradle 文件中的以下代码段会使应用在应用模块于调试模式下构建时使用库的调试构建类型,以及在应用模块于发布模式下构建时使用库的发布构建类型:

dependencies {
debugCompile project(path: ‘:library’, configuration: ‘debug’)
releaseCompile project(path: ‘:library’, configuration: ‘release’)
}
还必须在自己库的 build.gradle 文件的 android 块内添加以下代码行,以便将此库的非发布配置展示给使用它的项目:

android {
    ...
    publishNonDefault true
}

6.二次打包(封装)AAR

在aar里集成导入的aar,也就是二次封装aar的问题作者:brucevanfdm

为什么说二次打包aar是个坑呢?因为我没找到官方解决方案.那如何曲线避坑呢?aar其实就是个压缩包而已,解压后如下图所示:
这里写图片描述
AAR解压包Android Studio导入aar时也是将其视为一个module(library),使用其中的classes以及其他资源文件,那我们可不可以直接将其解压,直接导入?这样就避免了在aar的基础上封装成aar!跳过这个坑?实践证明确实是可以的。如果你要封装的aar只包含了jar包和so库,那就简单了,解压出来分别导入项目相关目录即可!不然可能就要手动合并某些资源了

7.aar中还引用了其他的module或者aar文件

当aar中引用了其他的module或者aar文件时,导入aar到项目中后会发现,其中aar依赖的module或者aar文件并没有导入到新的项目中,这时就会出现类似于下图中的异常java.lang.NoClassDefFoundError: Failed resolution of:
这里写图片描述
解决方法
将项目中依赖的aar或者module文件进行合并,合并很简单
步骤1
找到项目中app目录下的build.gradle文件,加入apply from: 'https://raw.githubusercontent.com/adwiv/android-fat-aar/master/fat-aar.gradle' 如图所示:
这里写图片描述
步骤2
在上面的build.gradle文件中将要合并的aar文件或者module文件做如图下处理

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

  // Order of dependencies decide which will have precedence in case of duplicates 
  // during manifest / resource merger 
  embedded project(':librarytwo')
  embedded project(':libraryone')
  embedded project('com.example.internal:lib-three:1.2.3')

  compile 'com.example:some-other-lib:1.0.3'
  compile 'com.android.support:appcompat-v7:22.2.0'
}

在上图中librarytwo,libraryone是要合并到当前project中的aar或者module文件。只是把原来的compile换成embeded就可以了。

猜你喜欢

转载自blog.csdn.net/u013309870/article/details/81812050