如何在 Android 中获取没有上下文的资源?

How to get resource without context in Android?

如果我有不同的资源名称,如大象、老虎和猫。我想创建一个接受资源名称和 return 可绘制对象的方法。然后我写了这个

public Drawable getDrawable(String name){
int defaultResId=  ResourceOptimizer.getResId(name,R.drawable.class);
return getResources().getDrawable(defaultResId);
}

其中 ResourceOptimizer

public class ResourceOptimizer {
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;
    }
}
}

但是问题是需要调用getResources() 在 activity 或片段中,否则您将传递上下文。

传递上下文可能会导致内存泄漏。特别是,当 它必须通过几个类。我想知道是否 有一些方法可以通过更方便的方式获取资源。 像 R.id.DRAWABLE_NAME

which the ResourceOptimizer is

Resources 已经有一个 getIdentifier() 方法。

But the problem is that getResources() needs to be called in an activity or fragment, otherwise you to pass the context.

正确。资源只能通过合适的 Context 获得。请注意 "suitable" 取决于具体情况;对于 UI,您几乎总是希望使用 activity 或片段中的 Context。例如,在 Android 10+.

上,您可能需要根据设备是否处于暗模式而使用不同的可绘制对象

Passing the context might cause memory leak

不适用于您在此处拥有的代码,因为您没有将 Context 或其中的任何内容保存在可能比 Context 本身更长寿的字段中。

I’m wondering if there is some way to get the resource by a better convenient way. like R.id.DRAWABLE_NAME

getDrawable()Context 上的一个方法。所以,调用 getDrawable(R.drawable.elephant).

您的代码试图专门 避免 使用 R.drawable,而不是使用 String 名称。所以,这变成:

getDrawable(getResources().getIdentifier(yourString, "drawable", getPackageName()))

其中 yourString 是您的资源的字符串基名(例如,"elephant")。

理想情况下,如果您希望在进程的生命周期内通过此代码多次检索相同的资源,则可以缓存 getIdentifier() 返回的值。反射并不便宜。