在运行我的应用程序的一小部分设备上,用户在通过首选项更改图像时会崩溃。完整堆栈跟踪:
java.lang.RuntimeException: Unable to resume activity {com.printandpixel.lolhistory/com.printandpixel.lolhistory.activities.MainActivity}: android.content.res.Resources$NotFoundException: Resource ID #0x1
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3346)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3377)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2728)
at android.app.ActivityThread.access$900(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1422)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5832)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x1
at android.content.res.Resources.getValue(Resources.java:2329)
at android.content.res.Resources.getDrawable(Resources.java:1846)
at android.content.res.Resources.getDrawable(Resources.java:1814)
at com.printandpixel.lolhistory.util.GeneralUtils.getDrawableFromName(GeneralUtils.java:226)
at com.printandpixel.lolhistory.util.GeneralUtils.getHomepageHeader(GeneralUtils.java:277)
at com.printandpixel.lolhistory.activities.MainActivity.onResume(MainActivity.java:252)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1255)
at android.app.Activity.performResume(Activity.java:6338)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3335)
... 11 more
此处引用的函数getDrawableFromName中的行如下:
return context.getResources().getDrawable(resourceId);
此方法的完整实现如下:
public static Drawable getDrawableFromName(String name, Context context) {
int resourceId = context.getResources().getIdentifier(name, "drawable", context.getPackageName());
if (resourceId > 0) {
return context.getResources().getDrawable(resourceId);
} else {
Tracker t = ((LoLHistory) ((Activity) context).getApplication()).getTracker(LoLHistory.TrackerName.APP_TRACKER);
t.send(new HitBuilders.EventBuilder().setCategory("EVENT").setAction("DrawableNotFound").setLabel(name).build());
return null;
}
}
据我所知,目前为止仅在Android 5上发生,而不是在所有Android 5设备上发生。据我所知,文档指定getIdentifier
应该返回0如果没有找到drawable但在这种情况下它返回0x1?我的应用程序中有数百个不同的图像,所有用户报告都将0x1作为无效ID。
假设resourcesIds为1都无效是否安全?
编辑:根据@ρяσѕρєяK建议,要处理弃用getDrawable(id),并在意外找不到资源时优雅地失败,我已编辑我的函数如下:
public static Drawable getDrawableFromName(String name, Context context) {
int resourceId = context.getResources().getIdentifier(name, "drawable", context.getPackageName());
Drawable drawable = null;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
drawable = context.getResources().getDrawable(resourceId, context.getTheme());
} else {
drawable = context.getResources().getDrawable(resourceId);
}
} catch (Resources.NotFoundException e) {
Tracker t = ((LoLHistory) ((Activity) context).getApplication()).getTracker(LoLHistory.TrackerName.APP_TRACKER);
t.send(new HitBuilders.EventBuilder().setCategory("EVENT").setAction("DrawableNotFound").setLabel(name).build());
}
return drawable;
}
答案 0 :(得分:0)
问题最终不是由getDrawableFromName
功能引起的。它实际上完全不相关:(。我在我的应用程序中有另一个函数来获取特定的默认偏好值,如下所示:
public static Drawable getHomepageHeader(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String headerImageName = prefs.getString(context.getString(R.string.pref_champion_header_name), "darius_600");
Drawable drawable = getDrawableFromName(headerImageName, context);
if (drawable == null) {
drawable = new ColorDrawable(ContextCompat.getColor(context, R.color.green));
}
return drawable;
}
此偏好设置在PreferenceActivity
中,其中包含以下ListPreference
:
<ListPreference
android:key="pref_champion_header"
android:entries="@array/headers"
android:entryValues="@array/header_values"
android:summary="Champion splash to appear at the top of the homepage"
android:title="Homepage champion"
android:defaultValue="1"/>
引用以下两个数组:
<string-array name="headers" translatable="false">
<item>Darius</item>
<item>Garen</item>
<item>Malphite</item>
<item>Gnar</item>
<item>Buccaneer Tristana</item>
</string-array>
<string-array name="header_values" translatable="false">
<item>darius_600</item>
<item>garen_600</item>
<item>malphite_600</item>
<item>gnar_600</item>
<item>buccaneer_tristana_600</item>
</string-array>
无论出于何种原因,某些设备defaultValue="1"
已解析为header_values
的第一个条目,而其他设备已解决为"1"
,导致"1"
传递给我的自定义getDrawableFromName
方法。要解决此问题,我只需将defaultValue
更改为显式等于header_values数组的第一个值"darius_600"