Android/Gradle: Where is this dependency embedded? - android

I'm using the new Android build system that is based on Gradle, together with the early access preview Android Studio. Now, I have two projects: an Android library project, and an Android app project (basically a demo for the library).
In the library project I have added a dependency to the gson library, so my build.gradle file looks like this:
dependencies {
compile 'com.android.support:support-v4:13.0.+'
compile 'com.google.code.gson:gson:2.2.+'
}
Still, everything works fine and dandy and I'm able to use gson in my library and then my app. But I want to understand where this library is embedded. I've opened both the .aar that is built by the library project and the .apk of the demo app. I was expecting to find the jars for the two dependencies in at least one of these, but I didn't.
So where are they?

From Android Tools website:
These items, plus the output of the compilation of the project’s own source code, are sent to dex for bytecode conversion and inclusion in the final APK.
In other words, they are in your *.dex file inside the APK.

As #SharkyXTS said, the code from any external dependencies is compiled into the final .dex file inside your APK. The reason why you can't find any references to these dependencies in the .aar is because there aren't any.
The .aar format is only supported through Maven for now, so dependencies are found through there. I believe there are plans to eventually support local .aar dependencies (without Maven), but the Android plugin isn't quite there yet. You can see this issue for more information.

Related

Android - create uber/fat aar, error on implementation

I want to create a single uber/fat aar. I have a library (libA) which is dependant on another library (libB) and I would like to bundle them together, preferably using gradle. This uber/fat aar will then be used in an app.
Initially I looked at 2 similar gradle plugins, shadowJar and fataar but due to version incompatibilities they were a no go. So to do this, I've created a custom configuration in my gradle file and added the dependencies:
configurations { privateLibs }
privateLibs ('libB.1.0.0#aar') {
transitive=true
}
compile configurations.privateLibs.asFileTree
I can then run gradle install to produce libA-1.0.0.aar.
When I inspect libA.aar and look at it's contents using
jar tvf libA-1.0.0.aar
I can see LibB listed under the libs folder:
BST 2018 libs/libB-1.0.0.aar
I've now created an app inclduing my new library libA-1.0.0.aar as a local dependency. Later it will be resolved through an external repository.
implementation files('libs/libA-1.0.0.#aar')
The app compiles and appears to be ready to run. However when I try to run the app in the android simulator it throws up an error message:
error: cannot access ExampleClass class file for com.sample.ExampleClass
ExampleClass is a class created in libB and implemented in libA. It appears as though libA has no knowledge of libB despite it being available in the libs folder of the libA aar. Is the build steps here wrong? Should this be done another way? Thanks in advance!

OSS license plugin doesn't include library module licenses

After migrating to Android plugin for Gradle 3.0 the OSS license plugin (https://developers.google.com/android/guides/opensource) no longer includes the licenses from the project's library modules dependencies. Only the "app" module.
I'm using com.google.gms:oss-licenses:0.9.1 and com.google.android.gms:play-services-oss-licenses:11.8.0
If I 'apply' the plugin to all my modules, the third_party_license data is generated in the raw folder for each module. But in the end only the data from the app module end up in the APK.
Is there any workaround for this problem?
Yes that is correct.
Based on my search on how the plugin works, the plugin would generate the data into the res/raw folder of the artifact (aar or apk, but not jar files) based on POM files it can get from the libraries. Then the rest of merging is done by Gradle Android Plugin, and not by the OSS License Plugin, which merges the res folders from all of the sources (dependency libs, modules, main app etc.). However here's is the issue, upon merging, the Android Gradle Plugin would choose one if there are duplicates of the same resource (link to explanation), and the one that is chosen is based on a priority, meaning since both the app module and the lib module are generating the R.raw.third_party_license resource which are duplicates, the one from the app module has a higher priority of being included than the one from the module hence the license information from the module are not included.
There are several ways of fixing this:
Include the same dependencies from your library module in your app module. This is probably the worst idea to do but it does not affect your app since Gradle would automatically resolve the dependencies without any issues especially if they will be of the same version, if they were of different versions then Gradle would choose the latest.
Rather than using a module dependency, publish the module to a maven repo (locally or remotely, here's a link to show how it could be done locally), and add it's dependency as such: implementation 'com.mygroup:library:1.0'. Don't forget to remove it from the project build.settings file. This would generate the POM file of the library module and hence get the plugin to read it and include it's library licenses. This means that the library should be compiled and published before compiling the app module, but also it could lead to some weird compiling issues and confusions when errors happen.
Unfortunately there is one more way that I thought would work however it didn't. It is by changing the dependencies in your library module to api instead of implementation. This would expose the library dependencies into the app module dependencies but would increase the build time of the project. But finally it didn't generate the raw resources properly because it seems that the OSS License Plugin only reads the dependencies from a POM file of library and in this case the POM file is not being generated even if the library module dependencies were exposed. Probably should post this as an enhancement or bug request to the developers of the plugin.

Does an Android .aar built with Gradle contain dependencies?

Not sure why I can't find any answers on this. If I convert my library project into an .aar using Gradle in Android Studio, does it retain all the dependencies of that module?
I'm asking because I'm trying to use a Gradle generated .aar locally, but it looks like only some of the original dependencies have been packaged. Namely, it complains that I'm missing 'OkHttp', but if I add it to the main project I get duplicate class errors.
Usually a library does not directly contain its dependencies. This does not matter whether it is an aar or a jar. Instead, the library declares its dependencies in the Gradle build file and they are resolved when someone uses the library.

Export libgdx project as Android library including dependencies

I have two, separate Android projects. One is a regular Android application and the other one is a libgdx project.
My goal is to be able to compile the libgdx project as an Android library into aar file, so I could use it in the regular, non libgdx, Android application (I'm going to start the libgdx game's activity from the regular Android project).
The libgdx project consists of several modules (I'm using only the android and the desktop modules), so in my libgdx project I can find 3 modules: android, desktop and core (where basically the whole game's code is resides). When compiling and running the game on Android, the android module kicks in, but it uses the core module as a dependency.
When trying to change the libgdx project into an Android library project and compiling it into aar, it seems like it lacks the needed dependencies (like the core module, in addition to some other dependencies).
How can I create an aar file from the libgdx project which has all the needed dependencies?
So eventually I managed to find a solution for my problem.
Lets start with the fact that my first impression was misleading, and the problem I had was not a libgdx specific problem, but a gradle "problem".
In short, the reason behind that is that the aar/jar files don't contain the transitive dependencies and don't have a pom file which describes the dependencies used by the library.
To overcome this behaviour you need somehow to specify the dependencies in your project. You can choose between 2 approaches:
first approach:
You can use a central repository, such as JCenter, and publish the project as library. In this case, gradle will be able to download the dependencies using the pom file which contains the dependencies list.
Second approach:
You need to manually copy all your dependencies to the libs folder. You can do this relatively easy by writing a small gradle task:
task copyCompileDependenciesToLibs(type: Copy) {
def libsPath = project.projectDir.toString() + "/libs"
from configurations.compile
into libsPath
}
This snippet will copy all your dependencies to the libs folder, and once you compile your library project the dependencies will be included.

Sample app runs fine with library as a module, but not as an external dependency?

I have a library which itself has a few dependencies, namely Realm, Retrofit, as well as a native library. The native library is on github and I can successfully pull it into my project via jitpack.
I have a sample app which im using to test this library. In my sample apps 'app' module build.gradle i my dependencies block looks somewhat like the following:
dependencies {
compile project(':sdk')
...
//compile realm,rx,retrofit, etc..
}
When doing this, my sample app works correctly.
Now lets say I either:
Grab the sdk's generated .jar file and put it in my sample apps /libs
Get the .aar and do the same as above
Put the repo on jitpack and try to download it via compile 'xxxx'
Trying to include the sdk in my sample app any of these other ways does not seem to work and spits out unhelpful errors.
What could possibly be the issue? I got a hint that it may be an issue with 'transitive dependencies' but am not sure where to start.
Ideas?

Categories

Resources