1

I have a question regarding performance and best approach for my Android code.

What I need to do is fairly simple, I want to dynamically assign a text value to a string ressource, depending on a int parameter:

For now I am using a big switch case

int messagesCategory;
if(extras !=null) {
        messagesCategory = extras.getInt("category");
    }

TextView titleText;
    titleText = (TextView) findViewById(R.id.headerTitle);

switch (messagesCategory) {
    case 1: titleText.setText(R.string.TitleMessageList1); break;
    case 2: titleText.setText(R.string.TitleMessageList2); break;
    case 3: titleText.setText(R.string.TitleMessageList3); break;
    case 4: titleText.setText(R.string.TitleMessageList4); break;

    case ...: titleText.setText(R.string.TitleMessageList...); break;

    case n: titleText.setText(R.string.TitleMessageListn); break;
    default: titleText.setText("a default title");  break;
    }

Let's say I have 30 lines in this switch... It works but for many cases, it looks there is a better way to achieve this. Unfortunately it does not look possible to assign something dynamic to R.string..

So my first question is: 1) performance wise, in this case, is it a problem to use a big switch for 30 cases or so? 2) what should be the best approach?

Thanks and have a good day

Don
  • 977
  • 3
  • 10
  • 28

4 Answers4

5

Simple,

int[] stringIds = {R.string.TitleMessageList1, R.string.TitleMessageList2,...};

int messagesCategory;
TextView titleText = (TextView) findViewById(R.id.headerTitle);
    if(extras !=null) {
            messagesCategory = extras.getInt("category");
            if(messagesCategory  <= n)
            titleText.setText(stringIds[messagesCategory]);
            else  titleText.setText("a default title"); 
 }

Now, there is no switch-case and comparison,, Basic Java and Android fundamentals make it to easy and short..

As R.string.XXX is an int value generated in R.java file you have to make a just int array of that values and just get value using your int messagesCategory. And directly set it to TextView..

user370305
  • 108,599
  • 23
  • 164
  • 151
  • Thanks for the answer, however on the first line of your code, it looks I would still need to enter manually the 30 Ids... Anyway to avoid that? – Don Jan 30 '13 at 09:15
  • Yes, make a String Array in `array.xml` file `res/values` directory of your application package. Now directly you can get the array in your code, use `getResource().getStringArray();` – user370305 Jan 30 '13 at 09:17
  • Look at http://developer.android.com/guide/topics/resources/string-resource.html#StringArray and http://stackoverflow.com/questions/4161256/android-reference-a-string-in-a-string-array-resource-with-xml – user370305 Jan 30 '13 at 09:18
  • Srtill not sure what the array is good for when you could pass the R.string.whatever integer right with the Intent, as I suggested in my answer. ;) – class stacker Jan 30 '13 at 12:37
  • [This solution](http://stackoverflow.com/a/14600678/779408) can be more efficient and faster. – Bob Jan 31 '13 at 01:43
1

You can also do this:

Field f = R.id.class.getField("TitleMessageList" + String.valueOf(messagesCategory));
int val = f.getInt(null);
titleText.setText(val);

It is fast without need to load all ids in the memory.

Enjoy!

Bob
  • 22,810
  • 38
  • 143
  • 225
0

switch case is the equivalent of GOTO in your code, and there is nothing to worry about with performance.

your code is fine, may not be nice but it works and it's efficient.

thepoosh
  • 12,497
  • 15
  • 73
  • 132
0
  1. I don't think 30 case statements don't hurt much except you execute them in a loop, iterating over an array, and such.

  2. Why don't you directly use the integers which R.string gives you? Is the mapping really necessary? You could pass the R.string identifiers around. Or else, you could have a lookup in an array if you're really worried about performance.

class stacker
  • 5,357
  • 2
  • 32
  • 65