What I want to achieve:
In sonar it is possible to track third party dependencies used throughout Projects by setting the property "sonar.libraries" and perhaps there are more benefits (such as detecting which violations are caused by external libraries?)
What I tried to do:
I set the value to build/intermediates/pre-dexed/debug/*.jar but this seems to have little effect.
Question:
Since it is no longer needed to use the "libs" folder for third party dependencies, what is the recommendation for the property called "sonar.libraries"?
We need to implement special processing when an Android project is detected. Correctly setting sonar.java.libraries is one of the requirements. A ticket already exists, feel free to vote or provide a pull request.
https://jira.sonarsource.com/browse/SONARGRADL-6
Update: we have released version 2.1 of the plugin (currently RC2) that natively supports Android projects. Properties sonar.java.[test.]binaries and sonar.java.[test.]libraries will be automatically populated.
The pre-dex folder also seemed to me to be the perfect candidate. Unfortunately, if you look into the jars in this folder, you'll see they contain no compiled class, but dex files. A dex file being a "dalvik executable", it's Android material, and Sonar can't do anything of it.
I managed to reference some of my dependencies, by declaring build/intermediates/exploded-aar/**/*.jar in the sonar.libraries property.
With this line you'll see all the "android librairies" (aar) that your project depends on. I've not yet managed to track all the other plain java libraires (jar)
Related
I'm using many applications in one project like :
So i have some questions here, Application must implement iterated libraries ?
Assume i have com.android.support:appcompat in my "app" gradle and have the same one in my "opencv-java" gradle the apk will compiled with both libraries and double the size?
If no, then what happened in compiling process?
If yes, How i can avoid this, is there a way or some thing?
Update :
If i have libraries (e.g: "volley", "support" etc..) in my app "gradle" and also i used it in my open-cv "gradle", that's make me able to remove those libraries from app "gradle", it's seems that main app that used compile project(':another-app') in "gradle" can use another-app libraries, with codes and assets, every thing.
the apk will compiled with both libraries and double the size?
No.
then what happened in compiling process?
Well, one of two things:
If you use compile "com.android.support:appcompat-v7" consistently, Gradle will only use one copy of that dependency.
Your build could fail with an error message complaining about duplicate Java classes, stemming from the duplicate libraries. This would happen if you are not actually using com.android.support:appcompat-v7 in one place, but instead are adding appcompat-v7 by some other means (e.g., directly compiling against a copy of that library project).
What can't happen is your double-the-size scenario, as you cannot have two copies of the same Java class in a single APK.
I understand this might be an extremely obvious and ridiculous question to ask, but please excuse me as I'm a beginner. I want to integrate this file into my project so I can call its methods:
https://github.com/RomainPiel/Shimmer-android
The question is, what do I do with it? Is it considered a "module", "library" or "file"? Should I manually copy the source files and create new classes in my project, and then call the methods from there? This would be the most straight-forward but in the "how to use" section in that package, it was mentioned "compile 'com.romainpiel.shimmer:library:1.4.0#aar'"
What I tried:
I downloaded the file as a .zip and then File->New->Import Module then navigated to the unzipped file. I believe I'm then supposed to add "compile 'com.romainpiel.shimmer:library:1.4.0#aar'" so I went to the gradle file to try to add it.
There are two: build.gradle (Module:app) and (Project:ProjectName).
I've tried adding to either and\or both and got this error: (Error:9,0) The project 'ProjectName' may be using a version of Gradle that does not contain the method. Did I do something wrong? Is it supposed to be this easy?
I would be extremely grateful to anyone who can point me in the right direction :)
You have three option
Using the GitHub Desktop you can clone the project and open it like a local project. Every change you make will be tracked. You can then commit and push using the GitHub Desktop. It's all UI and simple to use.
https://desktop.github.com
On Android Studio, when you open it, you'll see this, select GitHub and continue by adding your credentials.
You can then commit and push directly from that.
Using the terminal / command line.
If you are new, I recommend the first. It's simple to use and you get a hang of using it as it is the same steps with any project on any IDE you use.
Note: Downloading it as zip and then using it a bad idea because you're making it difficult on yourself because you can't keep track of changes and you'll have to re-upload everything every time. Which defeats the purpose of version control
If that GitHub account is not yours, then you'll have to fork the project, this way you'll have a separate version of the code on you GitHub on which you can modify. If it is yours then you're good.
Typically, you do not want to include external source code manually. This inhibits your build tool's (i.e. Gradle's) ability to manage that source code. It's very easy in Gradle to, say, set the version (like you have done by specifying "1.4.0") and then later remind yourself what version you have by merely looking at your build.gradle file. However, how would you go about doing that with raw source code? Typically developers do NOT put the version number of the source code in the actual source code - that's what they use their version control system (e.g. git) for, usually with tags.
Another aspect of Gradle is downloading and caching (and compiling) the external project for you. So that's nice.
With that said, you typically want to put that "compile..." line in your module's build.gradle file. Not the Project's build.gradle.
A module corresponds to your application (or library) that you are building or using. Some project's have multi-module configurations, where one module acts as a dependency for another (or several others). A Project in gradle is more of a 'meta' configuration that you can apply to all of your modules. The gradle docs recommend you focus on your module's configuration first and adjust the Project's configuration only if you have a specific need and reason to do so.
For the error you mentioned, you might have some unnecessary configurations in your build.gradle file, or the tool version numbers might not reflect what's on your system - if you copied and pasted from the internet, you might want to correct this by letting your IDE generate that file (the brute-force approach would be to create a new project entirely, and use its build.gradle files as a reference). Before you do that, you might want to check if your IDE provides any warnings inside that file.
You have to add the dependency to your module's gradle file.
There are two gradle file present in an android project. One is the project gradle and the second is the module gradle for each individual module.
You just have to copy the given
compile '......' in the dependency block.
I have a mature app that needs to have an SDK brought in that wraps the camera and makes it do some spiffy processing while it's running. The SDK has come to me in the form of some aar files but my app still lives in Eclipse. Because of my massive, steaming pile of a branding structure and deadlines for this integration the uncertain timeline required to fully migrate to Android Studio will not work (for now) so I'm going for converting the aars and using them in my app via Eclipse.
The problem I'm having is that I need to kick off the activity in the library but even though I fixed up all my build time reference problems, when running the app once I get to the point that is supposed to kick off the activity I get this error.
I've read through and double checked dozens of how-tos explaining how to consume the aar files and I think I've followed every step including:
Unzip the aar files and dress them up as individual library projects, including the file structure with the resources, the manifest, and the .jar
Make the project that needs the libraries add them as such
Add the .jars contained in the library projects to the build path (this step was not listed in most articles, and wasn't necessary for the project to build, but nevertheless it did not help my problem)
Declare the activity in your AndroidManifest.xml that the library brings in and declares in its AndroidManifest.xml
As I've said, everything looks good at build time, so I'm not sure what else to check. Because I'm reading that Gradle and Android Studio mashes manifests together really well, I have a hunch that it's something I'm supposed to regulate between the manifests but I don't know what it could be if that is it. I've wondered if I'm declaring the 3rd party's activity properly, but I'm not sure how to test it because the only way I can think to test it is to provide gibberish for the namespace but even then there are no complaints. I've also tried dissecting the .apk to look at the .dex file but I could not decipher anything useful.
My guess is that the library may not be building properly in eclipse - even before it's being added as a dependency to the application project.
Try looking at out/classes/* and making sure you have a .class file for the activity in question. I think the .class should actually be in the library as well as end up in the application project's out/ dir also.
If there are any native files (x.so) (as I would imagine there might be for spiffy camera stuff), you can look for the x.so files being included in the out/ dirs of both the library and application projects as well as the library.jar file.
Another option to maybe consider for this use case: https://github.com/ksoichiro/gradle-eclipse-aar-plugin
It seems that our app had a bad version of the appcompat-v7 support library. The .jars in it were different sizes than the one that comes with the SDK and several resources were missing. I have no idea how we ended up that way or where this bad version came from. Once I replaced it, things went great.
Later, I did encounter the need to drop in the .so files into the libraries I made that came out of the .aar files as Stad Kurdziel said in his answer, but that was causing a different error (the exception explicitly states that the .so is missing) and I arrived at the solution independently.
So, I've got a handful of "Utility" style classes in some of my projects. I'm curious if I can move them to an Android Library Project that contains all or most of my non-app specific glue code (wrappers and interfaces, mostly).
So, my question is what happens to the files I don't need in that library. I know Android Library Projects basically just copy their code into the other project, so if I say use 25% of the code in my "general purpose" library, will my app actually contain the bytecode for all 100%, or does it properly strip it down to only the stuff I need.
I had some issues with unused classes in Proguard in the past, so I'm just once-bitten, twice shy with the ADT now...
Unfortunately, all your projects will grow when the library is getting bigger - even if most contents of that library are not used. I tested it myself by creating an app A and a library L. If L is a library used in A, the classes.dex file (and therefore the A.apk file) is growing if I add more classes - even if they are not used.
To sum up: Right now I would create a basic library for certain things that are small and that may be used by many projects, and create a new library for every new component that is going to be larger and only is used by some projects. A good candidate for a new library would be a new UI component with multiple images defined in the resources. A good candidate for the base library are commonly-used methods and things like file caches, for example. Compiled code is compressed quite heavily for Dalvik, which you can see here. (The whole presentation is actually fun to watch :-)
Edit: If ProGuard is activated, it will also remove unused code for you. The default proguard.cfg is sufficient. It will not run on the (default) debug built, but when the final .apk is compiled. So it actually is possible!
I have used 3 level deep Android library projects successfully though it is kind of a pain. The primary use-case is when there are a set of resources and classes that you want to share across a few projects. Since I use a version control system, I would rather not use symlinks.
Note that Android Library projects also suffer greatly when dealing with resources. ADT will rebuild R.java once for each library, and each R.java will contain a copy of all resource ids from all libraries. The core problem here is that resources are regenerated for the entire project as a whole, and there is no way to "build a jar" for a dependency as would be expected with normal "libraries". We tried integrating with OpenFeint, and had all kinds of hell dealing with libraries and dependencies. I think we ended up just merging all the OpenFeint source and resource files into our own project and ditching the "Library" project as it was offering little value.
Android Library projects are a clunky way of sharing code between projects and have a number of drawbacks. I've found that everything accomplished with a Library project can also be accomplished with symlinks (symlink source into two projects). I've yet to find a usecase where an Android Library project offered something that wasn't easy to replicate with other, less fragile means.
I have an Android code base which uses APIs with settings to get different data for several apps. All apps use the same code base but with one or two design tweaks. So how do I re-use the main code base without having to copy the whole Android project each time?
iPhone uses multiple targets in the same project which works well. If android cant do this do I need to compile binaries of the code base in one project and then import into each new app project? If so how? I'm using Eclipse and am an intermediate Java developer.
Any help much appreciated!
Doug
Check out "Working With Library Projects" from the Android documentation. This should be just what you're looking for: http://developer.android.com/tools/projects/projects-eclipse.html#SettingUpLibraryProject
The current way to approach this issue if you are using Android Studio with Gradle is by using Gradle, Build Type + Product Flavor
http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
Build Variants
One goal of the new build system is to enable creating different versions of the same application.
There are two main use cases:
Different versions of the same application
For instance, a free/demo version vs the “pro” paid application.
Same application packaged differently for multi-apk in Google Play Store.
This new concept is designed to help when the differences are very minimum. If the answer to “Is this the same application?” is yes, then this is probably the way to go over Library Projects.
Note: This answer is basically obsolete now that one can create .aar libraries with resources. It still works, though, and there may be times when the portability of a .jar is desirable, so I'm leaving it here.
Blumer's answer is a good one, and you should definitely look into Android's idea of library projects. However, there is another alternative. If you have a module that contains only Java code, but no resources of any kind (images, layouts, etc.), you can compile it to a .jar file separately and use the resulting .jar in multiple application projects. It works like this:
Create a new Java project in Eclipse (not an Android project) and move the source code of your module there.
If your module references any classes from the SDK, you'll need to add the Android SDK .jar to the project's classpath (Project > Properties > Java Build Path > Libraries > Add JAR).
When your module is ready to use, bundle up its .class files into a .jar. You can do this manually, or you can look around to figure out how to get Eclipse to do it for you.
Copy your module .jar file into the "libs" directory of your app's main project.
Add the module .jar to the project's classpath (again, Project > Properties > Java Build Path > Libraries > Add JAR).
Now you should be able to build multiple apps using the same .jar, while maintaining only one copy of the module's source code.
Depending on your particular situation, this may or may not work any better for you than the standard Android library mechanism. But it's worth considering as an alternative.
The Android documentation recommends another approach if there aren't too many "different APIs" used.
The idea is to use reflection instead of making direction references to the code. Make sure to use optimized reflection instead of lookups every time.
References
http://developer.android.com/training/multiple-apks/api.html
http://developer.android.com/google/play/publishing/multiple-apks.html#ApiLevelOptions
You might want to consider using a source control system like Subversion (or GIT). Keep your most feature complete version in the trunk, and make branches for your separate versions that use different data sources or require minor layout changes, etc.