Android Application, Android Libraries and Jar Libraries

Sooner or later each successful platform provides tools for writing reusable components. For quite some time Android SDK supported only Jar Libraries. But there were no support for libraries that could contain both code and android resources.

In later releases Android SDK introduced support for Android Libraries, which could contain reusable android resources. But these Android Libraries had several very important limitations.

The first limitation was that Android Library couldn’t reference another Android Library. This was fixed in recent Android SDK updates. So now developers may create no-cyclic graph dependencies between their Android Components.

Another problem with Android Libraries, is that developer has to merge AndroidManifest.xml of Android Library files into application’s AndroidManifest.xml by herself (including activities, services, broadcast receivers, permissions, etc.) This is tedious task, especially if there are many Android Libraries in use. Though automatic merge is currently being developed and may be released in next releases of SDK.

Yet another issue with Android Libraries is that they can’t contain xml files (mostly layouts in this case) which use custom xml attributes (see bug 9656, I’ll write a separate post about this issue).

 

 

Android Library vs. Jar Library

The major logical difference between Android Library and Jar Library, is that Android Library contains both codeand resource, while Jar Library contains only code. This should be an indicator which kind of library when to use.

image

Android Library vs. Android Application

Android Library is essentially the same as Android Application: they use same directory tree for resources and code. The only difference between them on physical level is that Android Library has android.library set to true indefault.properties file (located in the root of project). If you set android.library to false or remove this property altogether you’ll convert Android Library into Android Application project.

image

Complex Dependencies

In latest Android SDK you can create as many Android Library dependencies as you want. You can have library A that depends on library B, which in turn uses library C. You just need to avoid circular dependencies.

image

Android Application and libraries

When you compile your Android Application build system goes through several steps (you can see a detailed description here):

  1. Generate R.java file
  2. Compile .java files into .class files
  3. All .class files and converted into dalvik bytecode (all .class files –> one .dex file).
  4. This .dex file is added into android .apk

image

 

This is important moment: all .class files are converted into dalvik bytecode format at compile time. This means that build system needs all .class files before it can start conversion.

Android Application and Jar Libraries

Jar Libraries are “imported” into .apk at build time. When android build system converts all .class files into .dex, the convertor (dx.jar) tool extracts all .class from referenced jar libraries and treats them as if they were locally compiled .class files.

  1. Note that  jar files are physically merged into  .apk file. There is no need to look for and load them in runtime, as your normal Java environment would do.

image

 
Android Application and Android Libraries

Note: I’m going to describe this one in greater details. So bear with me.

Let’s see how .apk is created when Android Application uses only one Android Library which has no other dependencies (i.e. does not reference other Android Libraries).

Single Android Library dependency

Let’s assume I have Android Application called “app” and Android Library called “lib-a”.

Here are steps build system goes through:

Note: Not all build steps are reflected in this description.

Note: This may become outdated as Android SDK evolves. Current Android SDK Level is 11.

1. Calculate “app” dependencies (in our case it will be “lib-a”)

2. Generate R.java classes:

Here is how build system handles this:

aapt package –f –m –auto-add-overlay

–M /absolute/path/to/app/AndroidManifest.xml

–S /absolute/path/to/app/res

-S /absolute/path/to/lib-a/res

-I /absolute/path/to/android.jar

-J /absolute/path/to/app/gen

 

Note that lib-a’s AndroidManifest.xml file is ignored!

Also note the –S parameter. This parameter is used to merge resources from several res folders. If app had string resource hello and lib-a had string resource hello, then the one from app would win, and the one from lib-awould be ignored. This happens because app’s res folder comes first in the command line.

Here is a description of –S parameter from aapt tool:

-S  directory in which to find resources.  Multiple directories will be scanned 
       and the first match found (left to right) will take precedence.

 

3. Compile .java files into .class files.

Note that on this step .java classes from app and from lib-a are treated as if they were from app. They are gathered together and compiled using one call to java compiler. There is no sign that we are using separate library at this step. Build system takes care about detecting all required .java source file paths.

Here is how build system handles this:

javac <other options> –sourcepath

/absolute/path/to/app/src;/absolute/path/to/app/gen/;absolute/path/to/lib-a/src

 

Also note, that if you have built Android Library before building Android Application, all .class files that were created during compilation of Android Library are simply ignored. This also means that if you have X different Android Applications reference one Android Library, this Android Library will be built times.

4. Convert all .class files into dalvik format and create .dex file

5. Package resources

This step is identical to step #2, except instead of generating R.java classes, this will produce special file with all merged resources in it.

6. Combine packaged resources and .dex file and save them into .apk file

image

Multiple Android Library dependencies

Let’s look at another example of Android Libraries: we have application called app, also we have lib-a, lib-b, lib-c, lib-x. Here is how they depend on each other:

image

You can download the source code for this app and libraries here and check default.property files yourself. Note the order values: uses(1), uses(2). This means that `app` references `lib-a` first, and  then references `lib-x`.

1. Calculate dependencies and their order.

Here is the order that build system determined for Android Libraries.

    [setup] —————— 
    [setup] Ordered libraries: 
    [setup] …/android-libs/lib-a 
    [setup] …/android-libs/lib-b 
    [setup] …/android-libs/lib-c 
    [setup] …/android-libs/lib-x 
    [setup] ——————

This order is important. It’s used when detecting which resources win if duplicates are found.

2. Generate R.java classes:

aapt package –f –m –auto-add-overlay

–M /absolute/path/to/app/AndroidManifest.xml

–S /absolute/path/to/app/res

-S /absolute/path/to/lib-a/res

-S /absolute/path/to/lib-b/res

-S /absolute/path/to/lib-c/res

-S /absolute/path/to/lib-x/res

-I /absolute/path/to/android.jar

-J /absolute/path/to/app/gen

 

Note how order printed by build system is reflected in this command line.

3. Compile .java files into .class files.

javac <other options> –sourcepath 

/absolute/path/to/app/src;/absolute/path/to/app/gen/;absolute/path/to/lib-a/src;absolute/path/to/lib-b/src;absolute/path/to/lib-c/src;absolute/path/to/lib-c/src

 

Note how order printed by build system is reflected in this command line.

4. Convert all .class files into dalvik format and create .dex file

5. Package resources from each each library and application into one file.

6. Combine packaged resources and .dex file and save them into .apk file

 

Summary on Android Libraries

Several important points you should take from this post:

  1. Source code and resources of all referenced Android Libraries are treated as if they were part of Android Application.
  2. Libraries’ AndroidManifest.xml files are ignored. Though this may change in future releases of Android SDK when manifest merging is added.
  3. Order of libraries determines who wins when identical resource names/ids are found across different libraries.

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值