Java library can't reference classes in dependency - android

I'm trying to build an annotation processor for an Android SDK, which is distributed as an AAR. This annotation processor should not be distributed with the SDK so I am building it as a separate JAR, in a separate project.
When creating the Java library project, I am unable to import classes (annotations in this case) from the SDK AAR. I've added the AAR as a dependency and verified that it is resolving it correctly (it comes from a custom Maven repository) during the build:
The AAR in question is obbsdk.aar
I've opened up the archive and ensured that the classes I am referencing are in the AAR that is being resolved. I'm not sure what else I should look at since it seems to me that the things to verify are that the classes are there and the AAR is referenced.
Any suggestions would be much appreciated!

I believe the fundamental issue I was running into was having a 'java-library' project depend on an 'com.android.library' project. I fixed the issue by moving the functionality I need to share out of the SDK into a separate java library and then having both libraries use that as a dependency.

Related

Multidex in an Android library project?

Is it possible to use Multidex inside a library project? It's not so hard to hit the 65k limit when you have libraries like Dagger, RxJava and Databinding. I'm really stuck here, any help would be really appreciated.
I am trying to 100% validate that this is true but based on how the normal build process works my hypothesis is that because your AAR consists of .class files and the normal android build process includes dexing all project files including libraries (AARs, and JARs) that adding multidex to your library really will just help with making sure that when they library is built in its root project that it is able to multi-dex properly.
Let's say you you build an AAR (which needs Multi-Dex) and then you import that aar into another project. Chances are you are going to need multi-dex on the project consuming the library as well because though the compiler doesn't need to compile the java classes it will still need to dex and do resource compilation on the entirety of the AAR.

How do I include sub-dependencies of a library with gradle and Android Studio?

I have an app and a library that I wrote. My issue is that when including the library as a jar (I see all of the classes included when decompiled),the app itself cannot interact with sub-classes from decencies of the library.
What is a good way to ensure that by including the library the app also pulls in the required dependencies?
What is a good way to ensure that by including the library the app also pulls in the required dependencies?
The best way is to publish the library in a maven repo (private or public).
In this way with gradle you will be able to download the library and all dependencies (described in the pom file).
Adding the jar (or an aar) in a project you have to add also the nested dependencies in the project since the jar and the aar don't contain the nested dependencies.

Java module referencing inside Android studio

I'm trying to compile Java module in Android Studio.
I'm also referencing android.jar in the module. So, yes, module is supposed to be Java, but uses android.jar as compilation reference.
The version SDK for this android.jar is irrelevant (I think, but it is 19 something).
(You might ask why if I need android.jar don't I use Android module instead of Java?, well it is intermediary step to restructure our Android project).
The problem I'm facing:
error: cannot find symbol variable SDK_INT
apply plugin: 'java'
dependencies {
compile project(':ATTLogger')
compile project(':BandwidthController')
compile project(':iwpstack')
compile files('libs/android.jar')
}
You see – IT doesn't want to recognize some… code clearly present in the android.jar.
And yes it sees import android.os.Build; and doesn't complain about it.
Here is my bukd.gradle:
Please help if you happened to solve this nuisance I've wasted half a day on.
Thanks!
If it is a Java only code (without any calls to Android API) then you can make it a JAR without adding a dependency to android.jar. Otherwise, if you have calls to Android API, you should make it AAR module.
From http://developer.android.com/sdk/installing/studio-build.html#projectModules :
Java library modules contain reusable code. The build system generates a JAR package for Java library modules.
Android library modules contain reusable Android-specific code and resources. The build system generates an AAR (Android ARchive) package for library modules.
Android application modules contain application code and may depend on library modules, although many Android apps consists of only one application module. The build system generates an APK package for application modules.
So to fix your issue, you should skip this "intermediary step" and make it an Android module right away.

Why do Google recommend copying libraries into your tree?

Google's instructions for using the Play Service API (for example) say:
Copy the /extras/google/google_play_services/libproject/google-play-services_lib library project into the source tree where you maintain your Android app projects.
Note: You should be referencing a copy of the library that you copied to your source tree—you should not reference the library from the Android SDK directory.
This seems ugly to me - why not reference it from the SDK directory? Is there some technical reason for this? Or is it so that you have explicit control over when it gets upgraded?
I'd like to point out that this is entirely a limitation of Eclipse, and it is indeed ugly.
The problem is that this library contains resources in addition to source code. Eclipse can only deal with libraries packaged as jar files, which, for the purposes of Android development, cannot contain resources.
So, in order for the library's resource to be compiled into the application, the library's source code, with the resources, must be added to your project.
If you move your build to Maven, and use an IDE that 'understands' Maven, then you can compile a library that contains resources as an 'apklib', and treat it as an external library, in a manner similar to a jar file.
The new Gradle-based build system is built on Maven primitives, but uses a different format for this, 'aar'. Hopefully, it will eventually also support apklib so that Maven builds and Gradle builds can inter-operate.
I just went through the exercise of converting an Android application to a Maven build, including the use of some apklibs. I can tell you that Eclipse with the m2eclipse plugin does not handle apklibs properly. Both IntelliJ and the new Google Android Studio (based on IntelliJ) do handle apklibs with no issues.
It's not about "Play Services Library" specifically. Just like any other libraries that the project makes use of, this library should be referenced from project's source tree.
In this case the external library is in the Android SDK directory and referencing from there is not a good practice too. So yes, it can be called "a technical reason".
Used libraries (Play Services library in this case) shouldn't be referenced from anywhere other than the project's source tree.

Building Android project with ant having a library project dependency on another library project

I have maybe this not so common setup:
(> = dependency)
Android project > Android library project 1 > Android library project 2
So I have an Android library project which has a dependency to another library project.
When I'm building project in Eclipse everythings works fine but I cannot get my build working with Ant.
First Ant compiles Android library project 2 which generates a classes.jar and puts this file in the bin folder.
Then Ant tries to compile the Android library project 1 but then I'm getting errors becouse it is missing classes from Android library project 2.
Well this is not so weird becouse the jar file is not included in the libs folders.
But in project.properties i've made a dependency to the library project 2 so why does Ant not copy the classes.jar to the libs folders of library project 1?
Well I can think of a solution to use an Ant task to copy the file to the libs folder, but then I have to modify the build.xml which I do not prefer.
** EDIT
The problem is that the R class is missing, when I look in classes.jar this java file does not contain the R class. So my solution would proberly not work.
This behaviour was caused by a change in R17 of the build tools: http://tools.android.com/recent/dealingwithdependenciesinandroidprojects
In a nutshell: R files for libraries are no longer packaged in the classes.jar for that library. However, since the pareent.R for the parent-library (project1 in your example) also contains the resource-references for the 'child' library (project2 in your example), you don't have to refer to the child-R anyway.
Replace all project2.R-import statements in project1 with project1.R import statements and you should be fine.
For ant to compile add dependency in ant.properties.
eg:
android.library.reference.1=../path/to/library
This sounds like a very brittle setup - you may have good reason for this, but could you instead decouple the libraries dependence on each other?
For example; implement a bridge pattern to translate the calls between both libraries, and make the calling Android project attach them. This way, you have no code in either library that depends on the other, and the only project that needs to handle dependency setup is your main project.
One of the main reasons for using a library is to make the code re-usable, this approach ensures someone (you, a colleague, your successor...) could plug in just one library and create their own implementation of the other one.
Here is another good article on applying the bridge pattern in Java: http://java.dzone.com/articles/design-patterns-bridge
Well the problem was that the R class was missing.
So i removed the R class dependency between the two library projects.
I don't know if this is fixable but i think it is bad practice any way.
Without this dependency Ant builds fine.
Old question, but like me, others might be banging their head on this...
The official answer is "it cannot be done", specifically:
At build time, the libraries are merged with the application one at a time, starting from the lowest priority to the highest. Note that a library cannot itself reference another library and that, at build time, libraries are not merged with each other before being merged with the application.
(extracted from the official documentation: "Referencing a Library Project").
Which means that anything goes, as there is no "clean" way to do it with the tools (and dirty methods are in order).
Hope it helps

Categories

Resources