Tool R Class Generator [Library Development Tool]

What is it?
This is a tool to automatically generate a B4A-type R class (in java) when developing libraries.

This is NOT required for any B4A use code.
This is NOT a requirement for library generation.

This is only required for a particular methodology of library wrapping. It allows you to access resource files from within the library without packaging it yet.

How was it built?
This is a python script turned to an .exe in pyinstaller.

How to run it?
Run this in the folder with the base class of the source you are trying to wrap. It doesnt really matter where you run it from, it will recursively go through every subfolder and analyze any .java files found in those folders.

What does it generate?
It will generate the R.java file in the same folder as itself.
The R class will have the following format (you will need to add the imports).

B4X:
public class R {
        public static final class color {
                public static int material_drawer_selected_text = BA.applicationContext.getResources().getIdentifier("material_drawer_selected_text", "color", BA.packageName);
                public static int material_drawer_secondary_text = BA.applicationContext.getResources().getIdentifier("material_drawer_secondary_text", "color", BA.packageName);
        }
        public static final class dimen {
                public static int material_drawer_margin = BA.applicationContext.getResources().getIdentifier("material_drawer_margin", "dimen", BA.packageName);
                public static int material_drawer_margin = BA.applicationContext.getResources().getIdentifier("material_drawer_margin", "dimen", BA.packageName);
        }
        public static final class string {
                public static int drawer_close = BA.applicationContext.getResources().getIdentifier("drawer_close", "string", BA.packageName);
        }
        public static final class id {
                public static int icon = BA.applicationContext.getResources().getIdentifier("icon", "id", BA.packageName);
                public static int name = BA.applicationContext.getResources().getIdentifier("name", "id", BA.packageName);
        }
}

Usage?
By embedding the R.java file in your library you will be able to access resources added using #AdditionalRes.

Bugs?
It generates a lot of duplicate identifiers.
Havent really tested it in a real library.

Download?
RGenerator2:
https://www.dropbox.com/s/sri0h96u0zyjp30/RGenerator2.exe?dl=0
RGenerator Version 1:
https://www.dropbox.com/s/9vhdilztbjxxe5x/RGenerator.zip?dl=0

Credits?
@warwound for identifying this method of accessing resources.
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
have you tried to start the tool from commandline?
Maybe there is an helpful output there...
 

somed3v3loper

Well-Known Member
Licensed User
Longtime User
have you tried to start the tool from commandline?Maybe there is an helpful output there...
I got this output
Error loading Python DLL: C:\Users\....\AppData\Local\Temp\_MEI42282\python24.dll (error code 126)
I found a suggestion to copy python24.dll to System32 but I found that it is already there .
Will try to find a solution .
 

somed3v3loper

Well-Known Member
Licensed User
Longtime User
If you changed PATH variable then you need to logoff and logon at least once to get this changes to work. I guess having the python-path in PATH variable is mandatory (right word?)...
Path contains C:\Python27\
and I restarted system .
 

Alberto Iglesias

Well-Known Member
Licensed User
Longtime User
Hey thedesolatesoul,

I have this xml in my res/values folder (named values.xml)

B4X:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">CEACommunicationsService</string>
    <string name="cea_communication_status_continue">Continue</string>
    <string name="cea_lib_blacklist_port">0</string>
    <string name="cea_lib_broadcast_listen_port">5000</string>
    <string name="cea_lib_broadcast_listen_timeout">7000</string>
    <string name="cea_lib_last_updated"> mon 30 of nov of 2015</string>
    <string name="cea_lib_last_updated_tag">Last updated:</string>
    <string name="cea_lib_platform">Android</string>
    <string name="cea_lib_protocol_version">1.0</string>
    <string name="cea_lib_service_version"> 0.4.0</string>
    <string name="cea_lib_service_version_tag">Version: </string>
    <string name="cea_lib_uri_scheme">cea</string>
</resources>

I put the RGenerator2.exe in the same folder where are res and executing, but the R.java generated is empty.

B4X:
import anywheresoftware.b4a.BA;

public class R {
}


Another question: after the R.java is generated, I can put in additionalres, directly in B4A?

Thanks
 

Johan Schoeman

Expert
Licensed User
Longtime User
Hey thedesolatesoul,

I have this xml in my res/values folder (named values.xml)

B4X:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">CEACommunicationsService</string>
    <string name="cea_communication_status_continue">Continue</string>
    <string name="cea_lib_blacklist_port">0</string>
    <string name="cea_lib_broadcast_listen_port">5000</string>
    <string name="cea_lib_broadcast_listen_timeout">7000</string>
    <string name="cea_lib_last_updated"> mon 30 of nov of 2015</string>
    <string name="cea_lib_last_updated_tag">Last updated:</string>
    <string name="cea_lib_platform">Android</string>
    <string name="cea_lib_protocol_version">1.0</string>
    <string name="cea_lib_service_version"> 0.4.0</string>
    <string name="cea_lib_service_version_tag">Version: </string>
    <string name="cea_lib_uri_scheme">cea</string>
</resources>

I put the RGenerator2.exe in the same folder where are res and executing, but the R.java generated is empty.

B4X:
import anywheresoftware.b4a.BA;

public class R {
}


Another question: after the R.java is generated, I can put in additionalres, directly in B4A?

Thanks
RGenerator does not extract the info for the R.java file from the res folder - it extracts the info from the java code / classes
 

Alberto Iglesias

Well-Known Member
Licensed User
Longtime User
OK. I doing wrong. I was putting in a folder with just ONLY this .XML, so the tool can´t find any class to references.

Now I get the r.java

B4X:
import anywheresoftware.b4a.BA;

public class R {
    public static final class string {
        public static int cea_lib_broadcast_listen_port = BA.applicationContext.getResources().getIdentifier("cea_lib_broadcast_listen_port", "string", BA.packageName);
        public static int cea_lib_blacklist_port = BA.applicationContext.getResources().getIdentifier("cea_lib_blacklist_port", "string", BA.packageName);
        public static int cea_lib_broadcast_listen_timeout = BA.applicationContext.getResources().getIdentifier("cea_lib_broadcast_listen_timeout", "string", BA.packageName);
        public static int cea_lib_uri_scheme = BA.applicationContext.getResources().getIdentifier("cea_lib_uri_scheme", "string", BA.packageName);
        public static int cea_lib_platform = BA.applicationContext.getResources().getIdentifier("cea_lib_platform", "string", BA.packageName);
        public static int cea_lib_service_version = BA.applicationContext.getResources().getIdentifier("cea_lib_service_version", "string", BA.packageName);
        public static int cea_lib_last_updated = BA.applicationContext.getResources().getIdentifier("cea_lib_last_updated", "string", BA.packageName);
    }
}


Now, what I need to do? Put this r.java in a folder B4A project and add line #AdditionalRes: ..\MyRes

?
 

DonManfred

Expert
Licensed User
Longtime User
Now, what I need to do?
See my video tutorial.
The R.java must be placed in the src folder where the javasources of the library is. (inside your eclipseproject)

You need to add the packagename to the start of the file!

Then compile your library and place the res folder of the lib somewhere and reference the dir with
B4X:
#additionalres: pathtores
in your b4a code
 
Top