I am new to Android development. I am stuck with some problems with no solution for more than a month. Please help me with if possible.
I am creating an android library having dependencies based on the following components.
- My library code
- layout and resources file
- Gradle dependencies to third parties.
First I think of creating .jar file for my library but then I figured out that laulyoit and resources files are not compiled with the jar. Then i decided to create AAR file. Please suggest if this one is right move or is there any other alternative???
Now the main problem I am stuck with gradle dependencies. We are creating a paid library that uses some third parties like google only available through Gradle. Now since I am creating an AAR file, there would be no Manifest.xml and Gradle file, how can i integrate the third paties with my own code. And We have the strict instructions that we must not tell the users of library to include that third parties to include. In simple words, we cannot let the users know what kind of third parties our library is using. So is there any way I can create an AAR file that also have the gradle dependencies pre-complied with this without revealing the user what servies we are using.
I can explain in more detail if there is any misuderstandings with above text. Please let me know your answers if possible.
Thanks In Advance.
Update 1
Here is my build.gradle for Library
apply plugin: 'com.android.library' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" multiDexEnabled true testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } dexOptions { preDexLibraries = false javaMaxHeapSize "4g" // 2g should be also OK } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.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:+' compile 'com.google.android.gms:play-services-vision:10.2.1' testCompile 'junit:junit:4.12' }
After the I am moving my .aar file to local maven and creating then using the output file in my application Project. Here is the gradle for same.
apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.jarvis.myapplication" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.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.company:mylibrary:1.0@aar') { transitive = true } compile 'com.android.support:appcompat-v7:25.3.0' testCompile 'junit:junit:4.12' }
4 Answers
Answers 1
If you create an .aar project there is a manifest file and it will get merged with the apps' manifest upon compile. That all works fine. You can use any gradle dependency in the .aar project, even proguard obfuscation and signing.
To compile an .aar library in the main app, put it like this in your dependencies
of your build.grade file:
dependencies { compile(name:'your_lib_name', ext:'aar') }
You have to copy the .aar file to the libs
folder in your app
folder.
But one thing is clear: If someone uses your .aar file, he or she can look at the merged manifest file in android studio any time and you can not hide your dependencies. At least, as far as I know. Android is driven strongly by open source libraries (even through maven) and in most cases you even have to include the licenses of your used external libraries, visible to the user as menu item or link in your app. Otherwise you violate licenses and maybe even Terms of Use in some cases. You may not hide them.
Answers 2
You can create an *.aar
file with all required dependencies in your Library project.
Now add this *.aar file either manually or as a dependency module to the targeted project. Once the main project is combined, this will give merged Android Manifest file
.
The following structure is having Library project (libraryModule) added as a dependency to main project. Again the libraryModule is having internal dependency for internallib
MainProject ===> libraryModule ===> internallib
As per your comment, the multidex issue can be resolved by adding the following in build.gradle
(Module: app)
defaultConfig { ..... multiDexEnabled true ..... }
Answers 3
Hi @user3572586,
The aar file doesn't contain the transitive dependencies and doesn't have a pom file which describes the dependencies used by the library.
It means that, if you are importing a aar file using a flatDir repo you have to specify the dependencies also in your project.
You should use a maven repository (you have to publish the library in a private or public maven repo), you will not have the same issue.
In this case, gradle downloads the dependencies using the pom file which will contains the dependencies list.
To hide paid lib from user better create package for individual library inside your project then generate .aar file. Myself i create one live stream lib same issue face on that time dependencies module's are move to inside my project then make .aar file.
Answers 4
First: AAR files have manifests. And, if you use gradle to build them, they'll have gradle build scripts.
So, the first part of your problem is moot. Just create an AAR library and add the dependencies using the gradle-maven plugin (gradle) or the maven-android plugin (maven).
For the second part, is a bit more tricky. What you want is essentially a shaded AAR or Uber-AAR, an AAR file which brings the dependencies bundled into itself. You can achieve that by using the maven-shade plugin or the gradle-shade plugin (depending on which system do you use to create the aar). With that approach, your clients can have a serious problem. You see, in java, your project works with the concept of dependency scopes and classpath. Scopes means the moment in time when the dependency is needed and who brings it. Classpath is the whole collection of classes used by a project, both the ones from dependencies or the ones from the project itself (so a client will always be able to know what are you using, because the compiler also needs to know). Therefore, you can't have several versions of a dependency in the path, because the classes would clash, rendering the project impossible to compile. That's why we usually don't attempt to hide which dependencies we are using; it allows easier resolution of conflicts. If you use a popular dependency (like google maps) you risk your library becoming a problem for your clients and therefore, being discarded. It would be best for you to develop the library with the designed contracts, then, a secondary plugin with a particular implementation using certain dependencies. That way you'll project would be easier to maintain and not tied to the dependencies. In that case, if the worst happens and your implementation's dependencies are incompatible with your client's projects, it will be easier to create a secondary implementation without compromising your code.
Link to the maven shade plugin: https://maven.apache.org/plugins/maven-shade-plugin/
Link to the gradle shade plugin: https://github.com/zawn/android-shade-plugin
0 comments:
Post a Comment