Java Question Compiling Libraries with R.java and #AdditionalRes

tchart

Well-Known Member
Licensed User
Longtime User
Just after some advice.
  1. Im wrapping an open source library which contains resources. The original library is an Android Studio project.
  2. The library source code contains references to R and wont compile without R.java.
  3. I've used thedesolatesoul's R generator tool to generate R.java and am able to compile the library. As far as I know the R.java is in the correct package etc.
  4. However when I include the resources in B4A using #AdditionalRes I get an "java.lang.IllegalArgumentException: already added:" exception pointing to the library resources as the issue.
  5. If I dont include the #AdditionalRes statement then the project compiles but throws an error saying resource not found.
  6. As a work around (see here) I renamed R.java to RX.java and updated any library source code reference to reflect this. This works great and the library works as expected.
Now thedesolatesoul suggested this isn't the best approach so my question is this;

What is the best approach to wrap a library that requires R.java without causing "already added" exceptions?

Thanks
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
Which github project do you wrapped here? url
How does the generated R.java looks like? Post the r.java-code
Please start reading this thread starting at #17 and follow my discussion with TDS
 

tchart

Well-Known Member
Licensed User
Longtime User
DonManfred, the library is this one; https://github.com/afollestad/material-dialogs

Thanks I have read that thread already.

R.java looks like this using TDS's tool

B4X:
package com.afollestad.materialdialogs;

import anywheresoftware.b4a.BA;

public class R
{
    public static final class dimen
    {
        public static int md_icon_max_size = BA.applicationContext.getResources().getIdentifier("md_icon_max_size", "dimen", BA.packageName);
etc
 

tchart

Well-Known Member
Licensed User
Longtime User
My b4a package name is com.tchart.md

I dont want to revert my RX.java changes back right now so I dont have the exact message. However, if you look at the image below you can see the R(X) class on the right from the library contains an attr entry called md_background_color. On the left if the R.java generated by B4A from the additonal resources folder and it too contains an entry for md_background_color. I did a comparison and there are 63 matches.

Both classes belong to the package com.afollestad.materialdialogs.

So perhaps there is just something specific with this library that causes this conflict?


2015-04-08 09_04_13-Java Decompiler - RX.class.png
 

thedesolatesoul

Expert
Licensed User
Longtime User
Interesting. (this might make RGenerator a moo point)
In the #AdditionalRes line, I guess you are using an additional parameter to specify the packagename.
I never do that...
so...
well...there are two ways to go about this...
either dont use RGenerator, dont make eclipse happy but export the jar regardless
or dont add the packagename at the end of additionalres, it will be compiled in the the main package R class.
(its so sad when i find these things out the hard way)
 

tchart

Well-Known Member
Licensed User
Longtime User
Interesting. (this might make RGenerator a moo point)
In the #AdditionalRes line, I guess you are using an additional parameter to specify the packagename.
I never do that...
so...
well...there are two ways to go about this...
either dont use RGenerator, dont make eclipse happy but export the jar regardless
or dont add the packagename at the end of additionalres, it will be compiled in the the main package R class.
(its so sad when i find these things out the hard way)

Just a couple of other points.
  • I cant generate the JAR file with SLC without R.java so I still require RGenerator
  • As the source code is Android Studio I havent got it to compile successfully in Eclipse
  • I think RGenerator (or some variation of it) would still be worthwhile either using my RX pattern or perhaps by altering the library source code references for R to use the BA.applicationContext.getResources() pattern instead (thus eliminating the need for R.java in the library).
Something to think about.
 

thedesolatesoul

Expert
Licensed User
Longtime User
I cant generate the JAR file with SLC without R.java so I still require RGenerator
I see, so its not a moo point!

As the source code is Android Studio I havent got it to compile successfully in Eclipse
It shouldnt matter hugely though. I usually just create a template java project, and drag the source files into the Eclipse project/src folder and they get copied there. I wonder how it works with AS.

I think RGenerator (or some variation of it) would still be worthwhile either using my RX pattern or perhaps by altering the library source code references for R to use the BA.applicationContext.getResources() pattern instead (thus eliminating the need for R.java in the library).
You shouldnt need to alter the library source code. Basically think of this as a double re-direction.
- Your library source lets say points to "import com.sourcelibrary.R;"
- Then our R.java generated by RGenerator should have the package name "package com.sourcelibrary"
- Inside this R.java it is getting resources from BA.applicationContext.getResources().getIdentifier("md_icon_max_size", "dimen", BA.packageName), and if you look closely you will see it is getting the identifier from the B4A project packagename. Right, so it is expecting the resources under that.
- Therefore you need to compile the resources under this package name, the java packer aapt.exe will pack the resources under an R.java which is under the B4A packagename. So essentially the library R.java is indirectly referencing the main R.java to access the resources.

It depends on how you are comfortable with this flow, but i cant see another way to do it, except if you really want to specify the packagename in the AdditionalRes then you need to use the same packagename in the getIdentifier method.
 
Top