Java module referencing inside Android studio - android

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.

Related

Equivalent of 'compileOnly' in Android.mk

I have a pre-built java library as a compile time dependency for Android library project(AAR). So while building it in Android Studio, 'compileOnly' is used so that the same gets linked in runtime when deployed with an APK.
However, I should also write an equivalent Android.mk for the library project. I am not able to find any reference to include a prebuilt java library in Android.mk. Can someone help me on this part.
I tried using LOCAL_PREBUILT_JAVA_LIBRARIES attribute, but the system threw an error:
error: dont use LOCAL_PREBUILT_JAVA_LIBRARIES anymore LOCAL_PATH=xxx.
This kind of dependency linking may look strange. Let me give some insight into it also. Basically I am building an application that has one small part being developed by a third party. The setter interface APIs for the third party are shipped in by me in the form of a .jar file so that they use the same as a compile time dependency and build an AAR out of it.
Now the third party project is to be included in my project build(AOSP). This brings a dependency that their module should be compiled for the AAR to get generated and my project uses that AAR to generate the APK.
For the AAR to get compiled and built, I need to link the prebuilt java interface library that is shipped in by me(mentioned in the first step).
Need an equivalent of 'compileOnly' used in build.gradle.

Java library can't reference classes in dependency

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.

Adding android.jar as a dependency for a module in Android Studio

I have decided to ask the question after my research did not reveal any useful solutions for my scenario which I believe should be quite popular.
My question is slightly related to this SO question, but the solution did not help in my scenario.
I want to create a Java module that will contain only my application logic. That said, I do not want it to be an Android Library module. I do not need to have manifest files and others for such a library. There will not be any Android activities in my application logic Java module. All Android-specific code will be in the Android module (called app). My Java module is called applogic.
So technically, I want my project to look like
AppProjectName
|-->app //Only Android-specific code here
|
-->src
|-->applogic //General, reusable Java-code here
|
-->src
In the app module settings, I add applogic as a module dependency.
From my Android app, I create objects defined in classes in applogic. I am able to do that easily.
And here is the thing. I want to use Android's logging capabilities (in android.util.Log). How can I use that for my Java library?
A possible solution that was stated in the SO question mentioned above was to add android.jar as a library to my applogic module. I was not able to do that in Android Studio. Any guidance will be greatly helpful.
Thanks!
If you're running within the context of a project created by Android Studio, you'll have a local.properties file giving the SDK location. Even if you're haven't got such an auto-generated file, there's nothing stopping you from creating it. It looks something like this:
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Tue Apr 04 12:34:41 BST 2017
ndk.dir=C\:\\Users\\smith\\Programs\\android-sdk\\ndk-bundle
sdk.dir=C\:\\Users\\smith\\Programs\\android-sdk
Either way, you can then use it in what I assume is the same manner as the Android Gradle plugin does:
dependencies {
Properties localProps = new Properties()
localProps.load(project.rootProject.file('local.properties').newDataInputStream())
implementation files("${localProps.getProperty('sdk.dir')}/platforms/android-15/android.jar")
}
Of course, you'll have to make sure you've downloaded the appropriate version of the platform using the Android SDK Manager, but if you're an Android developer you've probably already done that.
I have the same setup for one of my projects. I'm using android.util.Log and android.os.Build classes in a Java Library module.
In your app module, you should add applogic as a module dependency to build.gradle, which you have already done.
Then, in your build.gradle for applogic module, you should add android.jar dependency like this:
apply plugin: 'java'
dependencies {
compile files('libs/android.jar')
}
Since you are using android.util.Log which is available since API 1, then you can use any "android.jar" from any SDK Platform. Just copy it to your applogic module libs folder. Android Studio creates libs folder for Java Library modules.
So, your final project should look like
AppProjectName
|-->app
|
-->src
|-->applogic
|
-->src
-->libs
|
-->android.jar
There is another way to solve the problem w/o using 'android.jar', but it is very round-about.
Create an usual jar module (for example with name 'dummydroid') and add empty implementation of required android API:
// file dummydroid/src/main/android/util/Log.java
package android.util;
public class Log {
public static int e(String tag, String msg, Throwable tr) { return 0; }
//... etc
}
add the 'dummydroid' module as a compileOnly dependency to the applogic module
// applogic/build.gradle
...
dependencies {
...
compileOnly project(path: ':dummydroid')
}
That is all. The dummydroid object helps to resolve calls to android API during compilation of the applogic module. Because of the compileOnly type the dummydroid.jar is not transitively included in the compilation of the android app module --- and API references in applogic.jar are resolved to calls into the real android.jar on device/emulator.
The big shortcoming of this idea is that you have to make dummy implementation of all API those are used in the applogic.

Android Studio Java Library Module vs. Android Library Module

My desired end result is to have a Project that can output different productflavors of Mobile, Tv, and Wear apps, that share the same code-base. So I would like the codebase to be a dependency for all three app-types, where each app module would only contain activities and interaction with the codebase.
My first idea was to add a "Android Library Module" to my newly created project, but I noticed that this is really just a new app module with its own resources and everything. I would like the codebase to function more like a "Java Library", but it needs access to packages like "android.graphics.Color".
So in short, is the correct way of achieving this result to use a java library that has a reference to an android sdk or am i just going about this the wrong way?
Continuation of this question at:Does an Android Library need a manifest ,app_name,Icon?
There's no in-between. If you want access to Android APIs, then the library needs to be an Android library so that the build system can properly link it in to dependent projects. It's true that Android Libraries have resources and other things you may not need, but you can ignore those bits and treat it essentially as a plain Java library if you wish. Even if you're not using resources, you may find useful the ability to specify AndroidManifest.xml attributes to be merged into the dependent app.
The Android Library project doesn't build a fully-fledged APK as its output; it generates an AAR, which is conceptually similar to a JAR archive, but has resources and meta-information useful to Android projects.
Supplemental answer defining terms
The Android Studio documentation defines a module as follows:
A module is a collection of source files and build settings that allow
you to divide your project into discrete units of functionality. Your
project can have one or many modules and one module may use another
module as a dependency. Each module can be independently built,
tested, and debugged.
So basically a module is a subproject in your bigger project.
Types of modules
Android app module - The app module is usually what you are working with in a normal project. When you compile it you get an APK file that will run on a device. Here are the different types of app modules that exist:
Phone & Tablet Module
Android Wear Module
Android TV Module
Glass Module
Library module - The purpose of a library is to share code. For example, you could have a project with a couple different app modules. The common code that they both use could be located in the library.
Android Library - In addition to Java code, this allows you to also include Android resource files and a manifest. If you are making an Android project and are wondering what kind of library to use, then choose the Android Library. When compiled it creates an AAR (Android Archive) file.
Java Library - This only allows you to include Java code files, no Android resource files. This is useful for cross-platform code sharing. When compiled it creates a JAR (Java Archive) file.
Google Cloud module - This type of module is the Google Cloud backend for communication with your client side app.
One additional point that I've not seen well documented: An android library module can have a dependency on another android library module or java library module, but a java library module cannot have a dependency on an android library module.

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