How to bundle images in jar and use them in Android Application? - android

I am using some resources (images/drawable) in my own framework Android project to render some UI widgets. I just want to supply my framework as .jar to my clients. My clients can use this jar in their Android application libs.
The problem is even though I am exporting /res (i.e all images) directory at the time of .jar conversion, my client application is unable to use them. The reason I know is my client android application always look resources (images refereed as R.drawble.imgId) in client application resources but not in jar.
After goggling, I found a way to solve this is to supply my framework resources as zip along with .jar, so that my client applications will place supplied resources in their /res/drawable folder and no issues.
Now my Question is Is there any other way to achieve? How android is doing this for its view backgrounds?

For Distributed Jar, I found below method as simpler compare to others.
Please see below link for more
Packaging Android resource files within a distributable Jar file

Related

Java library (.jar) with resources in Android project

I want to use a regular Java library in an Android project. That library's .jar includes resources (text files) that are used by the library internally, i.e. it accesses these resources via a relative path within the .jar.
However, if I run the application on an Android device, I get an IOException telling me that the respective resource was not found.
Is it possible to have the library access its resources when run on the Android Dalvik VM? If so, what would I have to specify in my project?
Unfortunately it can't be done. "In general you cannot distribute your own package as easily as you would expect. The main problem is the autogenerated R file. You probably make some references to it - you have your layouts and drawables. User of your library will have his own R file - containing ids for his resources, not for the ones your library provides." (from This SO answer)

How to prepare a closed sourced SDK module on Android Studio?

Background
I'm working on an app that has become very popular, so much that a part of it is supposed to become an SDK (which would be available for developers), and the app will split to 2 apps (both use the SDK).
According to what I know, there are multiple ways to create an SDK module (previously called "project" on Eclipse) :
Completely open sourced (Android library) - all sources and resources are open sourced and can be modified. An example might be Facebook's SDK and a lot of Github repos.
a single Jar file, which can be closed sourced.
The problem
Sadly, I can't make the SDK open sourced, and it should relatively be protected vs prying eyes (obfuscated etc...).
The issue here is, the SDK needs to use some resources of its own (drawables, strings,...), and so far (because I didn't have a lot of experience with creating SDKs) I've found 2 ways to handle resources for SDKs :
use reflection and/or "context.getResources().getIdentifier" . This is quite messy, as I lose the whole "R" usage of the code. Also, it has issues with "styleable" , as I've written here. It also makes it hard to find unused resources.
even worse ways: put resources in assets folder, put files in a wacky way inside the jar file, ...
Note that a part of the SDK includes custom views (for example, classes that extend from TextView), so even if I do split the SDk into 2 modules- resources and java files, both might have issues of dependencies (each uses the other one).
The question
Is it possible to somehow solve this issue?
Is it possible for the code part of the SDK to remain closed sourced, reach the "R" file as usual, and make it easy for both me and whoever use the SDK ?
How would I then generate the jar file as being obfuscated via Android Studio? and is it possible to prepare it to to be used via gradle afterwards?
Can I maybe make the Android-library of the SDK into an obfuscated jar file and not worry about the "R" file ? I ask this because this way I could enjoy both worlds: for our apps, it would remain open sourced, and for third party apps it would be closed sourced.
EDIT: seeing that this is supposed to be easy, I've tried it myself. I've created a totally new POC project which has an Android library module called "sdkmodule", and added this class to it:
public class SdkClass
{
public String doIt(Context context)
{
return context.getResources().getString(R.string.app_name);
}
}
Then, I've made the app's module to use this one, and I wrote this code in it:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SdkClass sdkClass=new SdkClass();
Log.d("AppLog","string from SDK:"+sdkClass.doIt(this));
Log.d("AppLog","string with same ID name from app:"+getResources().getString(R.string.app_name));
}
What I expected is that the first log would print the string that's in the SDK module, and the second to show the string of the current project, but instead I got an exception:
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/example/user/sdkmodule/R$string;
On another try, I've got the same string that's used on the app itself (the one that uses the SDK module). And, on another run, the SDK produced the needed string as I've wanted.
How could it be? What should I do ?
In addition, I've tried to make a second activity in the SDK itself, and I've created a resource there that has the same resource name (used for a textView in its layout) as of the app itself, yet with a different value, yet when I've reached this activity, I've seen the one used by the app.
Here's the project, zipped (ignore the name of the folder, I wanted to try flavors too) :
https://drive.google.com/file/d/0B-PZZGk2vPohX25WUDNKTmotUTg/view?usp=sharing
The answer to your problem is to package and distribute your library as an AAR bundle
This format allows you to provide an obfuscated SDK jar and with its resources and the R mapping file.
This format is a standard and fully supported by maven-android-plugin (actually it's the replacement of the old APKLib format which supports only the distribution of source files).
Of course it's also supported by Gradle and Android Studio.
The Android Archive (AAR) format does what you want. It's like an Android-specific JAR file and contains compiled code, but includes its own resources and manifest. You can also include obfuscation as part of the build process. By default, the current version of Android Studio (1.2) and Gradle automatically build .AAR files for all library modules you create in your project.
You can change an app module into a library project that will publish an AAR file just by changing apply plugin: 'com.android.application' into apply plugin: 'com.android.library' in your module's Gradle file. The .AAR file will be placed in your MODULENAME/build/outputs/aar folder after each build. Some more information is available here.
Edit 1, after question updated:
The resources in your AAR get consolidated with the app module when the final APK gets compiled. The app resources will override the library's. This is probably by design, to allow people using a 3rd party library to customize its resources when creating their app, without having to rebuild the library. I think the easiest way to solve your resource conflict issue would just be to name your sdkmodule resources something more unique. Why not make the string key R.string.com_example_sdk_name or something?
No, the AAR libraries don't get obfuscated by default, but you can set up ProGuard in the Gradle build file for your AAR library to take care of this. Other tools are also available.

Using .apk files in a Java project, or the reverse

There are a few questions on SO about using .jar files in an Android project. But I am wondering if the reverse is possible - is it possible to use .apk files in a Java desktop project?
The reason for this is that I created a Java desktop app for object database management, but it needs the model classes from whichever application database it is looking at. With an object database, you need the model classes to define you database schemas. Side question - forgive me for my ignorance but can you run a runnable .apk in a desktop environment? something like this:
http://www.techday.in/how-to-run-android-apk-apps-on-computer/
Anyway, my goal is to kick off my personal object manager program from an individual android application. So in that case the .apk files would have to be able to talk with .jar files. If that fails, I could try just the opposite - kick off the jar file, and use the -vm argument as a location of the .apk files to put in the classpath. Either way. Which is easier? ---> .apk files in a Java program's classpath or .jar files in an Android program's path? Please, just expound away, I want all your thoughts.
APKs contain DEX files, not Java Classes so you would need to translate from one VM file format DEX Davlik to another. The link you provided is for Bluestack's Android VM which would run a APK as it is running the Android OS. If you want to look up how VirtualBox does things that would be the closest match.
The source for Android projects do use standard JAR files for libraries and class files are generated as part of the build process however once you start to package into something you can put on a Android device/emulator/environment you are in a different world.
However as the DEX file format is open-sourced, what you are trying to do isn't impossible, but it might be easier to use the intermediate class files instead.

Deploying Maqetta web workspace on MonoDroid

I'm researching the possibility of using Xamarin (MonoDroid) and Maqetta for building a cross-platform app. Before I ask my question I must admint to being a novice Android developer.
I'm curious to how I'm supposed to deploy the workspace I get from Maqetta on my android device. The Zip-file I download contains a very simple web project with two views in a .html file similar to this tutorial: http://www.youtube.com/watch?v=J0LneuYl280&feature=plcp
The thing is that the .zip file contains over 6500 files, but OK... It's no more than 8 MB total. I drag the entire folder structure into the Assets folder on Visual Studio. When building I get the following error:
Error 1 Invalid resource directory name: "assets". C:\Users\the\Desktop\Jobb\ImageCaptureApplication\ImageCaptureApplication\aapt.exe ImageCaptureApplication
I don't get anything else from this error.
Whats the story about this Assets folder? If I dig deep into the web workspace I got from Maqetta and remove the 'dojox' folder under "/lib/dojo/" now at least I'm able to compile and build the code, but my web page doesn't look like anything.
Is the file number too high for the Assets folder? Could it be too many levels in the directory tree from Maqetta? I understand there is a limit of 1 MB per file, but a search tells me that it doesn't look like I'm violating this rule.
It would definatly be too cumbersome to manually scan through each release of the Maqetta web project trying to filter out unnecessary dependencies..
Maqetta download size is a problem. You can select/deselect individual libraries, but the Dojo library, when included, is included in its entirety. You can edit the Dojo directory manually, as you have, or use the Dojo build script or the Dojo Web Builder (build.dojotoolkit.org) to create a smaller subset of the toolkit based on your usage. Maqetta integration with the Dojo Web Builder is a work in progress.
Was this "assets" folder part of Dojo? Did you identify where it was? The only problem I was aware of with the Android app builder is that it had a problem with underscores in filenames, but I believe that has been fixed.

Preloaded Android application with .so library file cannot be upgraded

I work for an operator, and we preload applications on Android phones.
However, some preloaded applications, once upgraded from Market, crash.
The problem is this:
- the application contains a .so library file
- in order to preload the complete application on a phone, the .so library file has to be placed separately into the lib directory (/system/lib/libXXXXjni.so)
- when the preloaded application is upgraded from Market and run, instead of the .so library file in the new APK being found, the older preloaded .so file is found first - causing a crash, because the two .so fiels have differing contents
Does anyone have a suggested work-around, or knowledge of the library-searching algorthim which may help me solve this?
One possible solution might be to simply rename the library file, but is that enough?
Thanks in advance...
When you preload, try putting the applications library in:
/data/data/com.package.foobar/lib/libXXXXjni.so
Renaming the library would work. Possibly using the app's version number as the name of the .so file. The build becomes more complicated though.

Categories

Resources