Android aar library doesn't contain dependencies - java

i saw similar questions, but not found accepted answers.
Problem - i have my own android library with some tiny functions.
My library uses others - f.e. Hawk (no sql database).
My library gradle file:
apply plugin: 'com.android.library'
buildscript {
repositories {
maven { url "https://www.jitpack.io" }
}
}
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
minSdkVersion 18
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'library.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.0.2'
compile 'com.github.orhanobut:hawk:1.23'
testCompile 'junit:junit:4.12'
}
Library works fine. And if i use it as project inside another project - it work too. But when i generate *.aar file (with gradle -> assembleRelease) and include into separate project - it fails. Project see ONLY MY library's class. Hawk com.orhanobut.hawk package and ofc others (if i will use then) are not visible. So ClassNotFoundException comes.
If i remove
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'library.pro'
the result doesnt change.
I tried to add the following line into proguard file (library.pro)
-keep class com.orhanobut.hawk {public *;}
-keep class com.orhanobut.hawk.* {public *;}
Result is the same.
So i have two question:
1 - what should i do to make my main project see my library's third party dependencies?
2 - is is possible to obfuscate my library's code (only mine, not dependencies)?

what should i do to make my main project see my library's third party dependencies?
The aar file doesn't contain the transitive dependencies and doesn't have a pom file which describes the dependencies used by the module.
It means that, if you are importing a aar file using a flatDir repository you have to specify the dependencies also in your project.
You should use a maven repository, private or public, to avoid the issue.
In this case, gradle downloads the dependencies using the pom file which will contains the dependencies list.

Another way to solve the problem of dependencies is to get the jar files of the dependencies you want to use and place them in the libs folder of your module. This will copy all the your dependency jars into your library's jar or aar.
Note that I have emphasized jar because you cannot include aar file in libs folder, gradle still doesn't support aar file inside aar out of the box. There are a few gradle plugins like fataar which solve that problem.

Related

How to insert a new dependency into a Gradle project?

I am very new to Gradle (I always have used Maven in the past.
I have to add this dependence to an Android project: https://github.com/nostra13/Android-Universal-Image-Loader/wiki/Quick-Setup
So, reading into the library documentation it only say that using Gradle I have to add this dependency:
https://github.com/nostra13/Android-Universal-Image-Loader/wiki/Quick-Setup
My problem is that, into my project, I have 2 differents build.gradle files:
1) build.gradle refered to the project:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
2) build.gradle refered to Module app
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.android.pastafromrome"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
}
What are the difference between these 2 files? Where exacctly I have to put the previous new dependency?
app\build.gradle or referred to Module app is specific for app module. As in Android Studio one can more than one module for a project. For example, an app module that you have now, you can add a watch module for your project that will have the work related to your smart watch, like watch faces etc.
build.gradle is a "Top-level build file" where you can add configuration options common to all modules.
You should add the dependencies to your required module. For example, as now you are adding UIL to your project which is directly related to your app module. So you should add it your app module in the dependencies part or function ( I honestly don't know what this is called, if someone can guide me on this I'll be grateful). So you dependencies part should look like this
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
}
You need to put dependency in Module level build.gradle file in dependencies section
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
Each project contains one top-level Gradle build file. This file is named build.gradle and can be found in the top level directory.
This file usually contains common config for all modules, common functions..
All modules have a specific build.gradle file. This file contains all info about this module (because a project can contain more modules), as config,build tyoes, info for signing your apk, dependencies
Any new dependency that you want to add to your application or module should go under build.gradle(Module app) and to add the dependency just write the compile statement that is given on the github page..
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
So, final code should be like..
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
}

How do you use custom views in Eclipse Android development?

I have downloaded a custom view and I want to implement it in my project but here's my dilemma: People use big terms or imply an action that I have never done before and have no knowledge of.
This is the view I am trying to download: http://androidcustomviews.com/holocolorpicker/
My questions are:
How do I import a view into an existing Eclipse project?
Which gradle file do I modify? There are 5 for me (build.gradle, gradle.properties, gradlew.file, gradlew.bat, settings.gradle).
Why do you have to add 'compile' to the gradle? Isn't this something the developer could just write in it?
How do I import a view into an existing Eclipse project?
It is not so much "importing a view" as it is importing the library that will let you use the view, which is explained below.
Which gradle file do I modify? There are 5 for me (build.gradle, gradle.properties, gradlew.file, gradlew.bat, settings.gradle).
One of the build.gradle files. One will look somewhat like this
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0-beta1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
that is not the right one as the comment suggest. You need to add it to the other one, which looks somewhat like this
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "xxxx"
minSdkVersion 23
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.larswerkman:HoloColorPicker:1.5'
}
See I added it at the bottom along with the other dependencies.
Now when you do a gradle sync, the library will be downloaded and automatically included in your project.
After that you can use the view in your xml file like any other view
With a regular view you use :
<View
..
.. />
Now with this custom view you use:
<com.larswerkman.holocolorpicker.ColorPicker
..
.. />
Why do you have to add 'compile' to the gradle? Isn't this something the developer could just write in it?
I'm not able to answer that, because it is a choice of the gradle development team. But basically with compile you say "here I have this library, please compile it into the project for me"
Yes, you need to add dependency to gradle.
dependencies {
compile 'com.larswerkman:HoloColorPicker:1.5'
}
After that, you can use this color picker in your layout, just adding like a simple view.
<com.larswerkman.holocolorpicker.ColorPicker
android:id="#+id/picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

Android Studio and openimaj

I am currently trying to build an android studio project using a dependency from the openimaj Java library.
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.mapinguari.myapplication"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'org.openimaj:openimaj:1.3.1'
}
Is my module build file. It reports no errors when syncing to the IDE.
However when I try to construct any of the classes in one of the source files the Android Studio does not recognize any of the classes from the openimaj dependency.
Any Help much appreciated.
Thank you!
I think it might be because you've specified a non-jar OpenIMAJ dependency (specifically you've told it to link against the OpenIMAJ master pom file, which only contains references to the different sub-modules). You probably need to actually choose the specific modules that you want - for example if your application is doing image processing, then add the dependency org.openimaj:image-processing:1.3.1.
Edit:
It seems that the batik svg libraries have a circular dependency somewhere that breaks Gradle (see https://issues.apache.org/jira/browse/BATIK-1098). This is what causes an eventual StackOverflowError. Additionally, something is pulling in xml-apis which will conflict with Android. Assuming you don't mind not have SVG image support, then the following should work:
repositories {
mavenCentral()
maven {
url "http://maven.openimaj.org"
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:18.+'
compile('org.openimaj:image-processing:1.3.1') {
exclude group: 'org.apache.xmlgraphics'
exclude group: 'xml-apis'
}
}
You might also want to add additional exclusions for dependencies that are not needed in your app - it seems that just including org.openimaj:image-processing pulls in lots of things that are almost certainly not going to be needed (I've created an issue for that here: https://github.com/openimaj/openimaj/issues/97).

How to include JAR dependency into an AAR library

Summary:
I have an AAR file that depends on a JAR file, when I build the AAR project, it doesn't contain the JAR code.
Details:
I have a Java SDK library project that contains code that we use for Java web projects and such, this library is created using Gradle and resides in an internal nexus server (as a JAR).
The goal is to provide an "Android configured" version of this JAR library through an AAR library that multiple Android Applications can use and minimize the effort (and boilerplate code) to implement it. This AAR file is also uploaded to the nexus server to be used by the Android Application projects.
My AAR project includes a gradle dependency for my Java SDK library (the JAR) but when built, the AAR doesn't include any classes from it.
Code:
This is the Java SDK project's gradle file:
apply plugin: 'java'
//noinspection GroovyUnusedAssignment
sourceCompatibility = 1.7
version = '1.1.1'
repositories {
mavenCentral()
}
jar {
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
testCompile 'org.apache.directory.studio:org.apache.commons.io:2.4'
compile 'org.springframework:spring-web:3.1.1.RELEASE'
compile 'com.google.code.gson:gson:2.3'
}
This is the gradle file for my AAR Project, note that I removed the Maven repository declarations to my nexus server from it. I guess it shouldn't matter for the sake of this question.
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "2.2.2"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.0'
compile ('com.mycompany:javasdk:1.1.1')
}
This is the gradle file for my Android Project, again I removed the nexus server references:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.mycompany.application1"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.0'
compile ('com.mycompany:androidsdk:2.2.2#aar')
}
NOTE: I initially solved the issue by adding the JAR in the lib directory of the AAR project, but this is undesired. It makes having a nexus server useless. It would be good that we can just bump the JAR's version number in the AAR project's gradle file and the update happens automatically at compile time.
NOTE2: I tried adding transitive=true to my AAR dependency in the Android Project but it didn't solved anything, the real issue is that when building the AAR project, the JAR project code doesn't get bundled.
You can add this task:
task copyLibs(type: Copy) {
from configurations.compile
into 'libs'
}
Dependencies will be downloaded from your Nexus, but when you need package the library, execute this task first and jar files will be copied and included inside final aar.
By default, AAR does not include any dependencies. Solution mentioned by #Hector should work for gradle plugin < 3.0. For Gradle plugin 3.0+, try custom config as mentioned here.
android { ... }
// Add a new configuration to hold your dependencies
configurations {
myConfig
}
dependencies {
....
myConfig 'com.android.support:appcompat-v7:26.1.0'
myConfig 'com.android.support:support-v4:26.1.0'
...
}
task copyLibs(type: Copy) {
from configurations.myConfig
into "libs"
}
None of the suggestions helped me for Gradle 4.6, so I wasted the whole day inventing my own.
Eventually I found a good Gist and modified it for my version of Gradle:
https://gist.github.com/stepio/824ef073447eb8d8d654f22d73f9f30b
The upper ones didn't work for me in android tools 3.6.2 with Gradle. 5.6.1 . For anyone having the same issue, using https://github.com/kezong/fat-aar-android in the end worked fine for me.

How do I import an external library into Android Studio?

I need to use the commons-codec-1.9.jar from the commons-codec-1.9 library supplied by Apache. I've used this as a library in another project in NetBeans, so I already had the required .jar file that I needed to import. I copied the jar file from the NetBeans project and put it in my app project (app:libs folder) and right-clicked and chose the "Add as library..." option. I added it to my project dependencies as well via File > Project Structure > Dependencies. I created the import for the library in the classes I've written that use the library, and I get no errors and the code builds. However, when I run the app, it breaks and throws a NoSuchMethod exception... even though it is there.
Here are the contents of my build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 20
buildToolsVersion '20.0.0'
defaultConfig {
applicationId "com.example.<path_stuff>"
minSdkVersion 17
targetSdkVersion 20
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile files('libs/commons-codec-1.9.jar')
}
Here is my settings.gradle
include ':app'
I have also recently been getting a build error after I removed the commons-codec stuff from the libs folder and tried to re-add it. The error says something along the lines of "Build failed: could not find task 'assemble' in project " as if Android Studio thinks this is another project. Can someone please help me understand what is going on here and where I am going wrong?
No such method error details:
java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.encodeBase64String
Edit: Realized I included the incorrect build.gradle file. Updated settings.gradle to remove the include statement. Included correct build.gradle and NoSuchMethod error.
Remove include ':libs:commons-codec-1.9: from your settings.gradle.
Add compile fileTree(dir: 'libs', include: '*.jar') to your dependencies block in your module's build.gradle file.
android {
...
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}
This will automatically compile any .jar file in your libs folder into your project.

Categories

Resources