Search Unity

Problem with R.class in custom unity player activity

Discussion in 'Android' started by sebbe, Jun 13, 2012.

  1. sebbe

    sebbe

    Joined:
    Oct 18, 2009
    Posts:
    6
    I'm developing a game with an Android plugin to access sensors and webservices.

    I can get everything to compile and run on the Android, however I cannot use R.string.app_name.

    As soon as I use the R class from my custom UnityPlayerActivity the app will not run on the Android and I get an error that it cannot find my R class.

    The strings.xml file is put in project-dir/Assets/Plugins/Android/res/values/ (as well as the res folder in my Eclipse project). The two res folders have identical content and generates the same ids.

    My Android plugin project in Eclipse has the same namespace as my Unity game, but it only works if I manually add the R.class from my Eclipse project into the jar-file it creates.

    Does anybody know what I'm missing to get Unity to create the R.class file from the Plugins directory?

    I'd be happy to share my example project if needed. Thanks!
     
  2. sebbe

    sebbe

    Joined:
    Oct 18, 2009
    Posts:
    6
    Ok, I have tried everything possible and I simply can't get Unity to genereate the R.class.

    I have made a repo case and submitted it as a bug.

    Find the project attached for reference. Link: https://dl.dropbox.com/u/3318808/AndroidRepo.7z
     
  3. Tseng

    Tseng

    Joined:
    Nov 29, 2010
    Posts:
    1,217
    That's "normal" due to the way how Unity3d builds the APK files.

    In short: When the R.java is created in eclipse, it will compile with certain ids for each. It's basically a class with static public fields containing resource IDs. When you create a jar file or APK from eclipse, everything works fine.

    When you copy the *.jar file into Unity Plugin/Android folder and then build your project, the resource files will be created one again. And the IDs will contain new values, while your already compiled classes (inside of the jar file you exported from eclipse) are only repacked into the APK instead of recompiled (there is no source, so it can't be recompiled).

    Because of this, your old compiled .class are pointing to invalid resource identifiers.

    There is a dirty (and ugly) workaround. It's ugly because, it makes refactoring a hell and it's not supported by Eclipse autocompletition.

    Java:
    Code (csharp):
    1.  
    2. Resources res = getResources();
    3. String text = res.getString(res.getIdentifier("some_text_id", "string", "com.mycompany.MyUnity3DGame"));
    4.  
    5. // The above is equal to
    6. String text = res.getString(R.string.some_text_id);
    7.  
    Also if you ever change the name, you have to change it at every place in code (or use a "public static final string" - which are the Java equivalent of constants).


    Edit:
    Unity way building the APK is really hacky and done badly. Unity should provide an export method where the built files can be exported into an folder inside of the eclipse project and then compiled with eclipse. This would solve many problems with APK builds.
     
    Last edited: Jun 17, 2012
  4. sebbe

    sebbe

    Joined:
    Oct 18, 2009
    Posts:
    6
    Thanks a bunch for your answer.

    I understand the part of the unique ids in the R.class, but I found somewhere that Unity will generate the same unique ids on build if the /Plugins/Android/res/ folder has matching content as the Eclipse project (as simply copy/paste takes care of that). The res folder is also copied to the staging area, but no R.class files are ever generated. I you inspect the .jar file created by unity in staging area, there is no resource classes.

    A wild guess would be that unity is replacing the resource referencing in source file when compiling and therefore never generates the R.class.

    Because of this, I can simply copy my eclipse generated R.class' into my plugin.jar and everything works. As this seem to be a hack, do you know how to make eclipse put the generated R.class into the jar? Or do I really need to create a post-compile script for extracting, copy, repack.