Android 公共库的建立方法


为什么要使用Android的Library工程?

简单的说就是减少代码拷贝。

An Android library project is a development project that holds shared Android source code and resources. Other Android application projects can reference the library project and, at build time, include its compiled sources in their .apk files. Multiple application projects can reference the same library project and any single application project can reference multiple library projects.

Android Library工程开发中需要考虑的问题

能把Android的Library工程打成一个单独的jar包发布吗?

如果工程是纯粹的Java文件,那么这和一个普通的java library工程没有区别, 可以打成jar包来发布。 在custom_rules.xml里添加如下两个target即可使用ant来编译jar包了:

<target name="jar" depends="-compile" description="Build binary jar">
    <jar destfile="${ant.project.name}.jar" basedir="${out.classes.absolute.dir}" >
        <include name="com/example/android/**" />
    </jar>
</target>

<target name="src-jar" description="bundle sources in a jar">
    <jar destfile="${ant.project.name}-src.jar" basedir="src"/>
</target>

但是如果Library工程有资源(string, layout等),针对 ADT r21 的答案是不行的。

You cannot export a library project to a JAR file. A library cannot be distributed as a binary file (such as a JAR file). This will be added in a future version of the SDK Tools.

针对Library工程有资源但又不想发布源代码的一种workaround的方法是把src目录进行编译后成jar包,然后发布的时候发布资源和jar包。在主工程中把Library工程的jar包放在libs目录下即可正常编译。 当然如果工程文件的AndroidManifest.xml里的内容需要合并到主工程的AndroidManifest.xml里。 合并AndroidManifest.xml的需求已经在Android Tools的Roadmap里,但何时能实现还未知。

资源冲突

如果在Library的strings.xml和主工程的strings.xml都定义了hello_world, 那么编译后的apk会优先使用主工程的hello_world。 为了避免冲突,建议在Library的工程中对所有资源添加前缀。

Since the tools merge the resources of a library project with those of a dependent application project, a given resource ID might be defined in both projects. In this case, the tools select the resource from the application, or the library with highest priority, and discard the other resource. As you develop your applications, be aware that common resource IDs are likely to be defined in more than one project and will be merged, with the resource from the application or highest-priority library taking precedence. To avoid resource conflicts for common resource IDs, consider using a prefix or other consistent naming scheme that is unique to the project (or is unique across all projects).

Library工程文件不能包含assets

Library工程不能在assets目录下存放raw资源,必须存放在主工程的assets目录下。

但是支持使用res目录来存放资源。

每个Library工程都有自己的R文件

每个Library工程在编译后都会在gen目录生成自己的R.java文件。

为Library工程创建测试工程

要的测试工程本身可以直接引用Library工程,测试工程本身也是APK。

通常的做法是在Library工程下创建一个tests目录用来存放测试工程。

需要在测试工程的AndroidManifest.xml<application>中加入让它成为一个测试工程。

<uses-library android:name="android.test.runner" />

同时在project.properties中加入对Library工程的引用:

# Project target.
target=android-8
android.library.reference.1=.. 


其次,本文主要介绍在android工程中如何将共用代码建成公共包方便其他工程引用、引用后的工程结构分析、library引入方式的优缺点

 

我的公共库已开源,可见TrineaAndroidCommon@Github,包含图片缓存下拉刷新静默安装及其他Android开发常用工具类,欢迎star和fork^_^。示例APK地址:TrineaAndroidDemo

 

1、java中公共库的创建和引入

熟悉java的朋友都知道在java中可以将公用代码提取出来新建工程,打包成jar包,然后通过外部依赖或是maven依赖加入其他工程使用。

 

2、android中公共库的创建和引入

使用android提供的is library功能创建公共库,android adt提供了公共库的创建方法,下面逐一介绍

a. 新建android工程

这一步同一般的android工程创建方法,如下

 

b. 设置工程属性为library

右击工程->properties->Android,将工程设置为是library,如下

 

c. android公共库的引入方法

右击需要引入library的工程->properties->Android,在library中添加之前新建的common,如下

这样我们就成功引入library了,对于引入后的工程结构分析可以参见本文下面第三部分介绍。引入后我们可以正常的引入java类,对于资源可以像在同一个工程中引入即可,因为library的资源被并入了工程中。

 

PS:如果这个时候工程编译出错,则可能是因为工程和公用library中资源的冲突问题,在后面的分析中我们可以知道引入library后,对于工程的资源会进行合并。比如library中现在含有icon.png的drawable资源,若调用者资源中也含有icon.png则会编译报错,这个时候我们可以将library中的icon资源删除,对于library来说尽量不要放这些drawable资源,我们甚至可以如下图红圈所示删除所有drawable资源文件夹,防止冲突发生。

当然删除icon后同时需要修改相应的引用资源的文件,如这里AndroidManifest.xml中的android:icon

 

3、引用后的工程结构分析

引入library的工程目录结构如下

从上图三个黄色标记的地方我们可以发现library的资源被并入了工程中,同时生成了两个一样的资源文件R.java。这样做的话,对于工程来说可以方便的调用library中的资源,跟在同一个工程中调用资源无甚区别。

a、library的资源被并入调用者工程中,并且相同资源值被覆盖

library中存在strings.xml内容如下

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <string name="hello">Hello World, AndroidCommon!</string>  
  4.     <string name="app_name">AndroidCommon</string>  
  5. </resources>  

调用者同样存在strings.xml,内容如下

Java代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <string name="app_name">TESTPROJECT</string>  
  4.     <string name="string2">testString</string>  
  5. </resources>  

最终R.java中的string我们可以看到同时存在hello、app_name、string2三个变量,即资源被合并。并且app_name的值为TESTPROJECT,即资源值被覆盖。

b. 资源一致性

修改上面红色标记的AndroidCommon_src中的AndroidCommon的内容,会发现library中的内容也会被相应修改

c. 编译一致性

修改library的资源进行编译会发现调用者工程也会同时被编译。 

 

 

4. library引入方式的优缺点

通过library方式成功引入了公用库

a. 提高了代码的复用率减少了开发量

b. 可以使得项目模块化以及更好的扩展

 

同时对于这种工程方式的引入还是觉得有一些不妥的地方

a. 通过源码引入,而不是通过类似jar包引入,从而对于library的修改导致所有引入该library都需要同时编译过于麻烦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值