Java library (.jar) with resources in Android project - android

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)

Related

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

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

Using Activities from Library projects

I have a Library project set up and a project which depends on this library project - Everything compiles fine and I've had the Dependent project running fine however;
I'm have an intermittent problem however while using an Activity from the Library project.
My Library project can be "unchecked" as a library project and the "picker" Activity can be run in isolation. Running the Library project in it's own right works fine with no problems.
When I use the Library project (and the "picker" Activity) from the dependent project it gives me either NullPointerExceptions (or historically DexOp) errors saying that the "picker" Activity can't find it's resources.
Can anybody tell me if they have experienced this before?
EDIT
Manually copying the layout.xml used by the Library project activity to the dependent project makes the project open the "picker" Activity correctly. Is this required?! Surely not? This further makes me wonder if there is a problem with merging/referencing the integer id's from R.java in the Library project.
EDIT
I'm not sure if this is of any consequence, but one of my Library projects is a wrapper around a set of custom views used in different front end projects.
These custom views each have an Activity so that they can be tested in isolation.
One of these view's has custom attributes, which while running in isolation work very well. However, it doesn't seem like the dependent project correctly pull's in the attributes and keep's them in their original namespace, causing the imported layout's to throw compilation errors:
[2012-05-16 12:07:28 - Project] D:\opt\workspace\CustomGlowList\res\layout\main.xml:14: error: No resource identifier found for attribute 'listId' in package 'com.company.library.glowlist'
[2012-05-16 12:07:28 - Project] D:\opt\workspace\CustomGlowList\res\layout\main.xml:14: error: No resource identifier found for attribute 'type' in package 'com.company.library.glowlist
EDIT
DexOp errors were solved by removing a duplicate file name which was present in the Dependent project. Not sure if the file name was the problem or the contents of the file.
EDIT
I've been unable to find a solution to this problem as of yet (although #yorkw's answer certainly helps with the xml attributes! Thanks).
I have managed to make this problem intermittent however:
I have gone through each of the library projects and ensured they all had their own namespace (ie, com.company.library.component1, com.company.library.component2 etc). After a couple of clean's (each project ordered with the correct precedence) this problem resolves itself, however does eventually come back when switching around library/not a library to test components.
Cause:
Issue 9656: Library projects don't support custom XML attributes for custom classes
Solution:
Upgrade to latest SDK & ADT version (fixed was released since r17) and use http://schemas.android.com/apk/res-auto as custom attributes' namespace URI, see Revisions for ADT 17.0.0:
Added support for custom views with custom attributes in libraries. Layouts using custom attributes must use the namespace URI http://schemas.android.com/apk/res-auto instead of the URI that includes the app package name. This URI is replaced with the app specific one at build time.
Related Topic:
Help with a custom View attributes inside a Android Library Project
not sure how you use the android library , but i've done this thing a lot of times without any problems , so please have a reading of the next things regarding using android libraries:
in order for an android project to use an android library project , you can either edit the "project.properties" and add the path to the library project there , or , much easier, right click the project (that uses the library project) , choose "android" category , and choose there "add" and choose the library project.
in order to make the android project to always open the android library project , also choose "java build path"->"projects" and choose the library project.
on the "project.properties" , try to set the target to the same target for both projects , and to the newest one that you have (latest now is 15) ,even if you can't test the app on this android version .
source files and all resources files (in the res folder) are ok to be used on the library projects.
assets folders cannot be used inside the library project . only on the android project that actually runs , the assets folder can be used . same thing goes to the proguard file .
the manifest of the library projects almost doesn't need to have almost anything . see this post for more information: https://stackoverflow.com/a/10445630/878126 . if there are activities on the library project that you wish to be able to access via the project that use it , don't forget to include them in the manifest of the android project (no need to write them in the manifest of the android library) .
remember to run lint before you export the app . it gives you plenty of warnings , but the most important warning is when you use too-new functions that cannot run on the range of APIs that you target . this is important for libraries since it's easy to get lost if there are multiple sources .
if you wish to extend activities on the android library , you need some kind of a method to go between them . the only way i know of is to extend the application and let it be the manager of how to create an intent for each of the activities . i think you can do other tricks , but they are all probably similar to this one.
if you have the same resource (any resource on the "res" folder) on both the android library and the android project, the one on the android project will replace the other one . this has advantages and disadvantages . remember that you can't have different file extensions for the same resource .
The problem was being caused by the R files from each of the Library projects not correctly being built and referenced. The resource files are built and referenced directly from the calling project.
Each of the Libraries need to have unique package as defined in the AndroidManifest.xml. This leads to each of it's resources being compiled in that unique namespace within the calling project alongside the Library jar which contains the class files.
The problem becomes intermittent when switching between a library and a runnable project because a clean and build needs to take place to regenerate these files as it isn't done automagically when unclicking the Use as library checkbox, where as the jar (and java classes) don't require as much coaxing for them to be correctly referenced as the library projects references them when acting as a Library.
This can lead to intermittent and also varying errors including missing references, DexOp and NullPointerExceptions depending on to what degree the R.java files have been mangled or partially built and what conflicts are taking places between packages.
I have same issue like, I have one library project and it has some activity.
When I was calling library project's Activity from my Main project, layout files resources were not getting loaded properly for the libray project's activity and giving "nullpointer exception" or "class could not be loaded", etc.
Solution: I have noticed that same layout file name is getting used in my Library project and Main project. I have just renamed those activity and it is solved.
May be this will help you.
I had similar issue when referencing Library project inside the Android App project. I deleted the R.java file from Library project so it generated again and App picked up the generated file. You should see the generated R.java file under your app project->gen->library_namespace_R.java.

How to consume reusable gui element/widget with resources in android

I try to use the dateslider in my android project to have a combined date-time picker im my gui.
The authors of the widget suggest to include the java- and resource-sources directly into my app.
1st try copy java and resources into main app:
Result: The widget java classes cannot compile because the resourceids R.xxxx cannot be resolved.
Reason: The widget classes are implemented in package "com.googlecode.android.widgets.DateSlider" and my app
has a different namespace "my.namespace.myApp" so that the resourceids come from my.namespace.myApp.R.xxx.
To fix this i would have to touch every widget java source to import my.namespace.myApp.
Is there a way to have 2 resource-sets with different namespaces so that there are my.namespace.myApp.R.xxx and com.googlecode.android.widgets.DateSlider.R in the main app?
2nd try put widget java+resources into seperate jar/library:
result: every thing compiled. but after appstart i get a runtimererror: the runtime cannot resolve the widget resource IDs from the jar/lib.
Note: i can call methods from the jar as long as these do not need resources.
So my question: what is the best way to consume a reusable gui element with resources in android?
I am using android 2.2.
Note: Android: How do I create reusable components? does not help because it tells you how to create library-projects.
update 16.3.2012
Since the current version 16 /17-pre of of the eclipse adt-tools do not support resources in jars (as of try 2) what is the best/easiest way to consume them until there is support for this?
update 4.4.2012
with the new R17-tools i succeeded to consume libraryproject-with-resources that creates the jar. Android-Lint helped me to find out what to change in the lib to make it usable.
eclipse-workspace
DateSliberLib
src
res
...
MyAppUsingLib
src
res
...
with this layout MyAppUsingLib is running fine
However I am still not able to use the DateSliberlib.jar alone
eclipse-workspace
MyAppUsingLib
src
res
lib
DateSliberLib.jar
...
This setting can be comiled but the app crashes because it cannot find the resources of the lib.
[update 2014-11-17]
6 months ago i switched from eclipse/ant-build to android-studio/gradle build which introduced *.aar files that are jar-files with android resources.
android-studio/gradle build can cope with resources in libs.
Is there a way to have 2 resource-sets with different namespaces so that there are my.namespace.myApp.R.xxx and com.googlecode.android.widgets.DateSlider.R in the main app?
No, sorry.
Note: Android: How do I create reusable components? does not help because it tells you how to create library-projects.
However, that is the right answer. Download the full project from their repo, import it into Eclipse, and mark it as a library project (Properties > Android). Then, add it as a library project to your app's project.
Eventually (which now appears like it will be the R18 version of tools or later), the tools should support packaging reusable components in a JAR, with resources, in such a manner that you can add them to a host project and the resources will be blended in automatically. Right now, that's not an option.

Android project as Jar Library

I am currently working on a Android Project where we are expected to merge our App with 2 more apps from vendors who wouldn't be sharing their code.So just wanted to know Is there any way we could just include there Source code as JAR Files in our project and then include their resources and point to them(I did do it using getResources().getIdentifier("splash", "layout", getPackageName()) But Its still not working ?? I think I have tried all possible methods so hoping you guys could help me with this.
To quote CommonsWare from this question:
Bear in mind that your packaged classes cannot reference resources (at
least not via R. syntax), and that JARs cannot package resources,
manifest entries, etc. If all you are trying to JAR up is pure Java
code (perhaps using Android APIs), then you should be fine.
Basically, you can only use JARs that contain pure java as libraries in your app, not entire other projects.
The Activities can be compiled into a jar and added to the main Android project and we need to add their project's resources into your Project. The only we could make it work is using the getResources().getIdentifier("splash", "layout", getPackageName()). Even the Widgets like TextView, Button and all those should be referred to using the getResources() method. Like, for example, If you want to perform a action on particular button then we need to identify them by getResources().getIdentifier("Button" /*id in the XML File*/, "id"/*type*/, getPackageName()).
One more thing: you need to specify all the Activities in your Main Android Project's AndroidManifest.xml file with their package name. I hope this solves something.
In order to support faster build times, the r16 tools are creating their own jar files inside of Android Library Projects. You can use this feature to solve this issue. If a vendor would like to release their Android Library Project but without source code, they can make a copy of that Android Library Project that contains everything except for the source code tree. Next, include the jar file from the original Android Library Porject (the one that the r16 tools built.) This will allow you to have a component you can distribute that does not require source code. The consumer of this new Android Library Project will need to manually add any necessary meta data to their own project's AndroidManifest.xml file as needed (Activities, Providers, Permissions, etc).

Create library for Android development?

I'm pretty new to Android development, but I have some experience with Java and Eclipse. I'm looking for ways to create re-usable libraries (controls, helpers, "standard" activities, etc.) that I could use in my own projects, but that could also be distributed to other developers without disclosing the source code.
Normally, I'd package the class files into a JAR file and any other developer could add it to the classpath and use the packaged classes.
How can I do that with Android projects? I've read about Android Library Projects, but as the documentation states they can not be packaged into a JAR, but will be compiled along with the project that references the library project. This means I also have to distribute the source code.
I've also read this post, which asks about the same question but didn't provide a satisfying answer.
So: Is there a way of compiling and packaging a set of classes and other files (including XML layouts, resources and stuff) and distribute only that package without any source codes so that it can be "referenced" and used like a JAR file by any other developer?
I've read about Android Library Projects, but as the documentation states they can not be
packaged into a JAR, but will be compiled along with the project that references the library
project. This means I also have to distribute the source code.
Not true. It does require a bit of extra packaging work, but you can compile your code to a JAR and distribute the JAR in the library project's libs/ directory.
So: Is there a way of compiling and packaging a set of classes and other files (including
XML layouts, resources and stuff) and distribute only that package without any source
codes so that it can be "referenced" and used like a JAR file by any other developer?
Use an Android library project. I have some stuff written up here that describes a bit more of the packaging options, plus pointers to some "parcels" that follow the conventions described therein.
Thanx for your solution. From what I understand, you still can not access the resources private to the library from within the libary code. So assume your library has a string resource named "my_lib_resource" under res/values in the library. You bundle this in the jar along with the source code. Can you access this resource from the library source code using something like:
int id = res.getIdentifier("com.example.mylib:string/my_lib_resource",null,null)
assuming your library package name is com.example.mylib.
For me this does not work.
Brave new world of dependency management:
http://tools.android.com/recent/dealingwithdependenciesinandroidprojects

Categories

Resources