tags:

views:

192

answers:

1

Hi,

R class on android has it's limitations. You can't use the resources dynamically for loading audio, pictures or whatever. If you wan't for example, load a set of audio files for a choosen object you can't do something like:

R.raw."string-upon-choosen-object"

I'm new to android and at least I didn't find how you could do that, depending on what objects are choosen or something more dynamic than that. So, I thought about making it dynamic with a little of memory overhead. But, I'm in doubt if it's worth it or just working different with external resources.

The idea is this:

Modify the ant build xml to execute my own task. This task, is a java program that parses the R.java file building a set of HashMaps with it's pair (key, value). I have done this manually and It's working good. So I need some experts voice about it.

This is how I will manage the whole thing:

Generate a base Application class, e.g. MainApplicationResources that builds up all the require methods and attributes. Then, you can access those methods invoking getApplication() and then the desired method.

Something like this:

  package [packageName]

  import android.app.Application;

  import java.util.HashMap;

  public class MainActivityResources extends Application {

      private HashMap<String,Integer> [resNameObj1];
      private HashMap<String,Integer> [resNameObj2];
      ...
      private HashMap<String,Integer> [resNameObjN];

      public MainActivityResources() {
          super();

      [resNameObj1] = new HashMap<String,Integer>();
      [resNameObj1].put("[resNameObj1_Key1]", new Integer([resNameObj1_Value1]));
      [resNameObj1].put("[resNameObj1_Key2]", new Integer([resNameObj1_Value2]));

      [resNameObj2] = new HashMap<String,Integer>();
      [resNameObj2].put("[resNameObj2_Key1]", new Integer([resNameObj2_Value1]));
      [resNameObj2].put("[resNameObj2_Key2]", new Integer([resNameObj2_Value2]));
      ...
      [resNameObjN] = new HashMap<String,Integer>();
      [resNameObjN].put("[resNameObjN_Key1]", new Integer([resNameObjN_Value1]));
      [resNameObjN].put("[resNameObjN_Key2]", new Integer([resNameObjN_Value2]));
      }

      public int get[ResNameObj1](String resourceName) {
          return [resNameObj1].get(resourceName).intValue();
      }

      public int get[ResNameObj2](String resourceName) {
          return [resNameObj2].get(resourceName).intValue();
      }

      ...

      public int get[ResNameObjN](String resourceName) {
          return [resNameObjN].get(resourceName).intValue();
      }
}

The question is:

Will I add too much memory use of the device? Is it worth it?

Regards,

+2  A: 

I'm new to android and at least I didn't find how you could do that, depending on what objects are choosen or something more dynamic than that.

The Resources class has a getIdentifier() method that will give you the resource ID given the name as a string. This uses reflection, so you would want to cache the results, perhaps using a LinkedHashMap as an LRU cache.

Is it worth it?

IMHO, not really. I would just use getIdentifer() or directly use reflection myself. In fact, I have directly used reflection myself (with the LRU cache) to address this issue.

CommonsWare
I see, for some reason I lost the `getIdentifier()` part reading docs. But, if I cache the results, isn't better to have all resources precached on start? I'm aware that maybe this will consume too much memory, but I don't know just how much. Maybe a little perecentage number will help me to dedice.
Sebastian
"But, if I cache the results, isn't better to have all resources precached on start?" No, for most apps. All you do by pre-caching is delay the start of the app (which the user might perceive) to eliminate a bunch of tiny delays as the app is used. Some apps, like a real-time game, might be speed-sensitive enough that the user will perceive those delays, and so caching up front may be good. Most apps, though, are not real-time games, and the cost of on-the-fly lookups will get swamped by other things (e.g., database I/O). Only pre-cache if you scientifically demonstrate that you need it.
CommonsWare