Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - getResources().getIdentifier replacement

Tags:

android

In android I am looping through the database and assigning text and image:

Cursor res = myDb.getAllData();

while (res.moveToNext()) {
    Actors actor = new Actors();
    actor.setName(res.getString(1));

    String th =  res.getString(11);
    Integer thumb = this.getResources().getIdentifier(th, "drawable", "mypackage");

    actor.setThumb(R.drawable.th);
}

However Lint suggests not to use getIdentifier - Use of this function is discouraged because resource reflection makes it harder to perform build optimizations and compile-time verification of code.

In database column I have just the image name (string). How can I replace getIdentifier?

Even if I change the DB column maybe directly to R.drawable.imagename, it is still a string and for setThumb I need a drawable.

like image 663
Darksymphony Avatar asked Mar 16 '26 20:03

Darksymphony


2 Answers

The best way is Using mapOf list like This example

val iconResourceMap = mapOf(
        "icon_1" to R.drawable.icon_1,
        "icon_2" to R.drawable.icon_2,
        // Add mappings for all the icons you have
    )

    for (i in 0 until data.length()) {
        val iconName = "icon_${i + 1}"
        val iconResId = iconResourceMap[iconName] ?: 0
}

Happy coding!

like image 95
Mohammed Qadah Avatar answered Mar 18 '26 10:03

Mohammed Qadah


Ok, so the only solution what I've found is here https://stackoverflow.com/a/4428288/1345089

public static int getResId(String resName, Class<?> c) {

        try {
            Field idField = c.getDeclaredField(resName);
            return idField.getInt(idField);
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        } 
    }

and then just calling:

int resID = getResId("icon", R.drawable.class);

This works very well, however some users reports, that after installing the app from Play store (not my app, but any with this method implemented and proguard enabled), after a while it will start throwing NoSuchFieldException, as more resources are mapped to the same class/field.

It can be caused by proguard but not sure. The solution is then to put the old way getResources().getIdentifier to the exception part of code.

like image 23
Darksymphony Avatar answered Mar 18 '26 09:03

Darksymphony



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!