Android getIdentifier返回0x1?
在运行我的应用程序的一小部分设备上,用户通过首选项更改图像时会发生崩溃。完整堆栈跟踪:Android getIdentifier返回0x1?,android,android-resources,Android,Android Resources,在运行我的应用程序的一小部分设备上,用户通过首选项更改图像时会发生崩溃。完整堆栈跟踪: java.lang.RuntimeException: Unable to resume activity {com.printandpixel.lolhistory/com.printandpixel.lolhistory.activities.MainActivity}: android.content.res.Resources$NotFoundException: Resource ID #0x1
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中的行如下所示:
返回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;
}
}
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;
}
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;
}
据我所知,到目前为止,这只发生在安卓5上,而不是所有安卓5设备上。据我所知,文档指定,如果未找到可绘制文件,则getIdentifier
应返回0,但在本例中,它返回0x1?我的应用程序中有数百个不同的图像,所有用户报告都将0x1作为无效id
假设1的ResourceSID都无效是否安全
编辑:根据@ρ∑ρѕρєK建议,为了处理getDrawable(id)的弃用,并在意外未找到资源时优雅地失败,我已将我的函数编辑为:
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;
}
}
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;
}
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;
}
问题最终不是由于getDrawableFromName
函数引起的。这实际上是完全不相关的:(.我的应用程序中有另一个函数来获取特定的默认首选项值,如下所示:
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;
}
}
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;
}
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;
}
此首选项是在首选项活动
中使用以下列表首选项
设置的:
<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>
大流士
加伦
墨菲特
啃
特里斯塔纳海盗
大流士600
加伦乌600
马尔皮特600
纳鲁600
海盗号:特里斯塔纳600
无论出于何种原因,在某些设备上,defaultValue=“1”
解析为header\u值的第一个条目,而在其他设备上,它只是解析为“1”
,结果是“1”
被传递到我的自定义getDrawableFromName
方法。为了解决这个问题,我只需将defaultValue
更改为显式等于头值数组aka的第一个值“darius_600”
getDrawable
方法在API级别22
中不推荐使用getDrawable(int,Theme)
在级别22的更高版本上。@ρцσѕρєK谢谢你的提示。我已经更新了我的get drawable方法来解决这个问题,并且失败了。请参阅有问题的编辑。@alexgophermix你也可以使用ContextCompat.getDrawable(上下文,int-id)
来自支持库。@b1izzard ah这将基本上取代修正案中if-else的需要。感谢您的建议