How to load a JAR from Assets folder at runtime - android

How to load a jar file from assets folder of android application during run time. Loading from assets folder is my requirement. Is there any way to do this. Please help ..

I got the answer.I am adding this answer here. Because this may be helpful to some others searching.
There are steps to accomplish this.
You have to make a copy of your JAR file into the private internal storage of your aplication.
Using the dx tool inside the android folder, you have to generate a classes.dex file associated with the JAR file. The dx tool will be at the location /android-sdks/build-tools/19.0.1 (this file is needed by the Dalvik VM, simply jar can not be read by the dalvik VM))
Using the aapt tool command which is also inside the same location, you have to add the classes.dex to the JAR file.
This JAR file could be loaded dynamically using DexClassLoader.
If you are making a JAR from any one your own library, you have to do this steps (1-4) every time when there is a change in your library source code. So you can automate this steps by creating a shell script(in Mac/Linux/Ubuntu) or batch scripts(in Windows). You can refere this link to understand how to write shell scripts.
Note : One situation for implementing this method is, when it is impossible to add the JAR files directly to the build path of core project and need to be loaded dynamically at run time. In normal cases the JAR files could be added to the build path.
please check this link for the detailed code and implementation.
How to load a jar file at runtime
Android: How to dynamically load classes from a JAR file?

Related

Android how to extract *.so file during execution

I have one android myLibrary.jar file. But myLibrary.jar file will load the native 3 different so file. I have a.so, b.so and c.so.
When i using in my own application, it just simply put the jar file to the Android Dependencies and all 3 so files put in the libs/armeabi of the main application package.
When deploy and install on the device, these so file will be in the data/data/my-appname/lib/*.so.
Now i need to provide the sdk solution. The user side doesn't want the main application. They just want the myLibrary.jar. So i am considering about packing all 3 *.so files to the jar. I searched for the how to add to the so files to myLibrary.jar. But i still don't understand.
In this following post:
[Ant]How to add .so file into a jar and use it within jar(set the java.library.path)?
It mentioned about adding the so file to the jar and extract at runtime. But i still don't understand how to achieve that.
After trying that mentioned in the following post:
Creating a product SDK: How do I add a native lib (.so) and a jar with the SDK I am creating?
After my sample application reference the the compiled jar that included the .so file. After installing to the device, the libs/armeabi/xxx is not unpacked on the install. So i would like to know how to extract them dynamically and save them to data/data/my-appname/lib/ so that i can use with System.loadlibary(.so).
Thanks a lot.

How can I add a jar to an APK & make the APK refer to it without Eclipse?

This may seem a bit weird, but I need to implement it.
I have an APK & I dont have its source code.
Now I can break the apk , modify & repack it, but while doing so, I need to add my custom jar to it & make the app/apk refer this library/jar at run time.
If I just create a folder libs inside the apk & put my jar inside, I get a NoClassDefFound error.
Any idea how to implement it using ANT or any other tool ?
Thanx in advance
The Jar(s) you attach in your android project, are not copied into APK.
What happens is that, The code of your Jar(s) file becomes part of your Android code. That means you can not simply place(or copy) Jar files in your APK.
But, There is a way around. In APK, your source code can be found in the classes.dex file.
What you need to do is, follow the steps
1 - Extract APK using winRAR
2 - Convert classes.dex to Jar using dex2jar
3 - Extract Jar file
4 - You will have source code in *.class, You can use JdGUI to convert it to *.java.
Now, you can create new android project and use the code.
This is not possible. All the classes are already compiled. You will need to "build" the APK again so that proper references could be remapped.

Android dx usage

I have a jar file created out of an android application, because I marked it as "Is library" in eclipse at creation time. Now the DexClassLoader is not able to load this file because it doesn't have an entry marked classes.dex. This looks like a standard jar. How can I convert such a jar into a dexed jar with dx that DexClassLoader can load? Any help appreciated!
You can use the dx tool from the sdk, from the command line. Something like:
dx --dex --output=dexed.jar hello.jar
Works for me. Integrating such things into your build process is something of a black art, largely involving hacking up the ant buildscripts provided by the SDK. If your library is only occasionally updated it might be viable to do it manually.
In my case, I keep the dexed.jar in my resources/raw folder. At runtime, I copy it from there into the filesystem, then pass the filesystem path to the DexClassLoader. It's... a little bumpy.
Android Libraries are not meant to be started on device. They only can be included as part of Android Projects, which will convert all referenced Android Library .jar files into single shared .dex file and package them to .apk file.
If you want to test your Android Library and it's manifest actually has some entry points for that, then the only way to do so is temporarily change Android Library to Android Project (by checking off that check bar in settings).

Adding .so files to Android project

I am trying to add SQLCipher to my project. I am able to link the jar files to the project but there is problem linking the .so files provided.
Due to that I am getting UnSatisfiedLinkError when i try to open the DB.
Can anyone please let me know the best possible way to add .so files to the project and get it running.
In addition to jar files you need to include .so files. In my project I have:
jar files in project_root/libs/
.so files in project_root/libs/armeabi/
Also make sure that you have added the .jar files properly. Go to Project Properties -> Java Build Path -> Libraries tab make sure commonc-codec.jar, gueva-r09.jar, sqlcipher.jar are added there.
EDIT
1) Add a single sqlcipher.jar and a few .so’s to the application libs directory
2) Update the import path from android.database.sqlite.* to info.guardianproject.database.sqlite.* in any source files that reference it. The original android.database.Cursor can still be used unchanged.
3) Init the database in onCreate() and pass a variable argument to the open database method with a password*:
SQLiteDatabase.loadLibs(this); //first init the db libraries with the context
SQLiteOpenHelper.getWritableDatabase(“thisismysecret”):
Can you use the adb shell command to verify what files are being deployed to your simulator after it has been unpacked. I have seen an issue where the .so files are not packaged up in the .apk file before, which is due to the IDE not pointing to the correct native library path for your application.

how to reference an asset in a library project

In a class belonging to a Library project I call:
webview.loadUrl("file:///android_asset/info.html", null);
Unfortunately, this only works if I duplicate the file info.html into the Application's project asset folder as well.
Is there a way to tell an Android library code: "look for this file in the library's assets folder, not in the application's assets folder" ?
This answer is out of date, the gradle build system and AAR files support assets.
From the Android Docs:
Library projects cannot include raw assets
The tools do not support the use of raw asset files (saved in the assets/ directory) in a library project. Any asset resources used by an application must be stored in the assets/ directory of the application project itself. However, resource files saved in the res/ directory are supported.
If you want to include files from a Library project, you'll need to put it in the resources instead of the assets. If you're trying to load HTML files from your library project into a WebView, this means that you'll have to go a more roundabout method than the usual asset URL. Instead you'll have to read the resource data and use something like loadData.
This is now possible using the Gradle build system.
Testing with Android Studio 0.5.0 and v0.9 of the Android Gradle plugin, I've found that files such as
MyLibProject/src/main/assets/test.html
are correctly packaged in the final application and can be accessed at runtime via the expected URL:
file:///android_asset/test.html
You can achieve this by creating a symbolic link in the project's asset folder that points to the directory in the library project.
Then you can access as below:
webview.loadUrl("file:///android_asset/folder_in_a_libary_project/info.html", null);
Okay. Ive been stressing out and losing sleep about this for a while. Im the type of person that loves API creation, and HATES complicated integration.
There arent many solutions around on the internet, so im quite proud of what Ive discovered with a bit of Eclipse Hackery.
It turns out that when you put a file in the Android Lib's /assets folder. The target apk will capture this and place it on the root of the APK archive. Thus, making general access fail.
This can be resolved by simply creating a Raw Java Library, and placing all assets in there, ie (JAVALIB)/assets/fileX.txt.
You can in turn then include this as a Java Build Path Folder Source in
Project > Properties > Java Build Path > Source > Link Source.
Link Source
Click on Variables. and Add New Variable, ie VAR_NAME_X. location : ../../(relative_path_to_assets_project)
Click Ok
Now, when you build and run your app, the assets folder in the APK will contain your (GLOBAL Library) files as you intended.
No need to reconfigure android internals or nothing. Its all capable within a few clicks of Eclipse.
I confirm that Daniel Grant's approach works for at least the following situation: target project does NOT have an asset folder (or the folder is empty, so you can safely delete it).
I did not setup any variable.
Simply setup a LinkSource as follows (just an example)
Linked folder location: /home/matthew/workspace_moonblink/assetsForAdvocacy/assets
Folder name : assets
The "assetsForAdvocacy" is a Java project, (created with New- Project - Java Project) with empty src folder, and a new folder named "assets", which now provides the entire assets folder for the target project.
This is a fairly straightforward way within Eclipse to provide assets re-use across many different projects IF they do not already have assets, good enough to get going with. I would probably want to enhance it to become a content provider in the long run, but that is a lot more development.
My project accesses the assets with the following code:
String advocacyFolderInAssets = "no_smoking/"; //a folder underneath assets/
String fn =advocacyFolderInAssets+imageFilename;
Bitmap pristineBitmapForAdvocacy = getBitmapFromAsset(context, fn);
I use Motodev Studio 3.1.0 on Ubuntu. It would not let me 'merge' a new assets folder in the new assets-only project onto an existing assets folder in the target project.
If you want to use a setup where multiple derivate products are created from one library you might consider using svn:externals or similar solution in your SCM system. This will also do the trick that static assets like online help may be versioned seperately from the android source code.
I found this older question, it might help you, too.
This is the official way Google uses to archive this (from the above post): Link

Categories

Resources