异常 - 无法从资源中找到可绘制的图标
Exception - Could not find icon drawable from resource
背景
大家好。我正在制作一个应用程序,它有一个主 activity 和一个自定义 object 列表。每个项目显示一张图片、一个标题和一个副标题,全部取自该项目的 object 属性。
在第一个版本的应用程序中,当点击一个项目时,object 被发送为 Parcelable
并带有 Intent
到另一个 activity,显示object 具有的所有属性,包括图像。当时图片的属性只有图片的Resources
ID,所以我只需要加载那个ID的图片即可。
在我当前的版本中,我添加了一个新的 activity 允许用户设置 object 信息以便将新的 object 添加到主 activity ] 列表。但是,用户从图库中选择图像。为了面对这个问题,我将初始 ID 属性更改为 Drawable
,这样我就可以直接分配 Resources
图片和画廊挑选的图片。
这给了我一个 FAILED BINDER TRANSACTION
错误,所以我决定将图像保存为 byte[]
以避免这种情况。
现状和问题
我的自定义 object 构造函数获取 Drawable
并使用以下方法将其转换为 byte[]
:
private byte[] drawableToBytes(Drawable img)
{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
((BitmapDrawable)img).getBitmap().compress(Bitmap.CompressFormat.PNG, 50, stream);
return stream.toByteArray();
}
为了从Parcelable
得到object,我使用了下面的方法:
public CentroMando(Parcel in)
{
String[] datos = new String[11];
in.readStringArray(datos);
this.setAbreviatura(datos[0]);
this.setNombre(datos[1]);
this.setImagenBytes(Base64.decode(datos[2], Base64.DEFAULT)); // <----- Image
this.setLugar(new Lugar(datos[3],
Double.parseDouble(datos[4]),
Double.parseDouble(datos[5]),
Double.parseDouble(datos[6])));
this.setComandante(datos[7]);
this.setEnlaceCentroMando(datos[8]);
this.setEnlaceLocalizacion(datos[9]);
this.setEnlaceComandante(datos[10]);
}
要将 object 转换为 Parcelable
:
public void writeToParcel(Parcel dest, int flags)
{
dest.writeStringArray(new String[]
{
this.getAbreviatura(),
this.getNombre(),
Base64.encodeToString(this.getImagenBytes(), Base64.DEFAULT), // <----- Image
this.getLugar().getNombre(),
String.valueOf(this.getLugar().getLatitud()),
String.valueOf(this.getLugar().getLongitud()),
String.valueOf(this.getLugar().getDireccion()),
this.getComandante(),
this.getEnlaceCentroMando(),
this.getEnlaceLocalizacion(),
this.getEnlaceComandante()
});
}
要从 byte[]
获取 Drawable
,我使用以下命令:
public Drawable getImagenBytesDrawable()
{
byte[] datosBitmap = this.getImagenBytes();
Bitmap imagenBitmap = BitmapFactory.decodeByteArray(datosBitmap, 0, datosBitmap.length);
return new BitmapDrawable(imagenBitmap);
}
现在,当我点击 ListView
中的项目时,一些加载没有任何问题并且显示图像和属性正常,但其余的关闭应用程序没有任何错误 Logcat.我必须删除 Logcat 中的过滤器才能真正找到问题所在:
2019-11-14 01:33:18.287 2110-14522/? E/ActivityManager: Transaction too large, intent: Intent { cmp=com.example.ud4_propuesto_1/.DatosCentroMandoActivity (has extras) }, extras size: 594808, icicle size: 0
2019-11-14 01:33:18.287 2110-14522/? D/GamePkgDataHelper: notifyAppCreate(), pkgName: com.example.ud4_propuesto_1, sendRet: true
2019-11-14 01:33:18.287 2110-12153/? D/GamePkgDataHelper: getGamePkgData(). com.example.ud4_propuesto_1
2019-11-14 01:33:18.287 2110-12153/? D/GameManagerService: handleMessage(), MSG_APP_CREATE. ignore. pkgName: com.example.ud4_propuesto_1
2019-11-14 01:33:18.289 2110-14522/? E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 598680)
2019-11-14 01:33:18.289 2110-14522/? E/ActivityManager: Second failure launching com.example.ud4_propuesto_1/.DatosCentroMandoActivity, giving up
android.os.TransactionTooLargeException: data parcel size 598680 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:1145)
at android.app.IApplicationThread$Stub$Proxy.scheduleTransaction(IApplicationThread.java:1897)
at android.app.servertransaction.ClientTransaction.schedule(ClientTransaction.java:129)
at com.android.server.am.ClientLifecycleManager.scheduleTransaction(ClientLifecycleManager.java:47)
at com.android.server.am.ActivityStackSupervisor.realStartActivityLocked(ActivityStackSupervisor.java:1862)
at com.android.server.am.ActivityStackSupervisor.attachApplicationLocked(ActivityStackSupervisor.java:1199)
at com.android.server.am.ActivityManagerService.attachApplicationLocked(ActivityManagerService.java:10029)
at com.android.server.am.ActivityManagerService.attachApplication(ActivityManagerService.java:10097)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:170)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:4162)
at android.os.Binder.execTransact(Binder.java:739)
2019-11-14 01:33:18.290 2110-14522/? I/ActivityManager: Process com.example.ud4_propuesto_1 (pid 25813) has died: fore TOP (214,2655)
附加信息
我将 Drawable
图像保存为 xxxhdpi
。
导致应用程序崩溃的项目图像大小分别为 410 KB、393 KB 和 393 KB。其余图像重量小于 345 KB。
我测试过,只有带有较重图像的项目才会导致应用程序崩溃。
问题
有什么办法可以解决吗?
Intent 总大小限制为 1MB,因此无法在其中发送位图。
您应该让您的数据对象接受从预设(可绘制资源)或图库(url 到缓存文件?)中选取的图像,然后解析它并相应地加载图像。
背景
大家好。我正在制作一个应用程序,它有一个主 activity 和一个自定义 object 列表。每个项目显示一张图片、一个标题和一个副标题,全部取自该项目的 object 属性。
在第一个版本的应用程序中,当点击一个项目时,object 被发送为 Parcelable
并带有 Intent
到另一个 activity,显示object 具有的所有属性,包括图像。当时图片的属性只有图片的Resources
ID,所以我只需要加载那个ID的图片即可。
在我当前的版本中,我添加了一个新的 activity 允许用户设置 object 信息以便将新的 object 添加到主 activity ] 列表。但是,用户从图库中选择图像。为了面对这个问题,我将初始 ID 属性更改为 Drawable
,这样我就可以直接分配 Resources
图片和画廊挑选的图片。
这给了我一个 FAILED BINDER TRANSACTION
错误,所以我决定将图像保存为 byte[]
以避免这种情况。
现状和问题
我的自定义 object 构造函数获取 Drawable
并使用以下方法将其转换为 byte[]
:
private byte[] drawableToBytes(Drawable img)
{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
((BitmapDrawable)img).getBitmap().compress(Bitmap.CompressFormat.PNG, 50, stream);
return stream.toByteArray();
}
为了从Parcelable
得到object,我使用了下面的方法:
public CentroMando(Parcel in)
{
String[] datos = new String[11];
in.readStringArray(datos);
this.setAbreviatura(datos[0]);
this.setNombre(datos[1]);
this.setImagenBytes(Base64.decode(datos[2], Base64.DEFAULT)); // <----- Image
this.setLugar(new Lugar(datos[3],
Double.parseDouble(datos[4]),
Double.parseDouble(datos[5]),
Double.parseDouble(datos[6])));
this.setComandante(datos[7]);
this.setEnlaceCentroMando(datos[8]);
this.setEnlaceLocalizacion(datos[9]);
this.setEnlaceComandante(datos[10]);
}
要将 object 转换为 Parcelable
:
public void writeToParcel(Parcel dest, int flags)
{
dest.writeStringArray(new String[]
{
this.getAbreviatura(),
this.getNombre(),
Base64.encodeToString(this.getImagenBytes(), Base64.DEFAULT), // <----- Image
this.getLugar().getNombre(),
String.valueOf(this.getLugar().getLatitud()),
String.valueOf(this.getLugar().getLongitud()),
String.valueOf(this.getLugar().getDireccion()),
this.getComandante(),
this.getEnlaceCentroMando(),
this.getEnlaceLocalizacion(),
this.getEnlaceComandante()
});
}
要从 byte[]
获取 Drawable
,我使用以下命令:
public Drawable getImagenBytesDrawable()
{
byte[] datosBitmap = this.getImagenBytes();
Bitmap imagenBitmap = BitmapFactory.decodeByteArray(datosBitmap, 0, datosBitmap.length);
return new BitmapDrawable(imagenBitmap);
}
现在,当我点击 ListView
中的项目时,一些加载没有任何问题并且显示图像和属性正常,但其余的关闭应用程序没有任何错误 Logcat.我必须删除 Logcat 中的过滤器才能真正找到问题所在:
2019-11-14 01:33:18.287 2110-14522/? E/ActivityManager: Transaction too large, intent: Intent { cmp=com.example.ud4_propuesto_1/.DatosCentroMandoActivity (has extras) }, extras size: 594808, icicle size: 0
2019-11-14 01:33:18.287 2110-14522/? D/GamePkgDataHelper: notifyAppCreate(), pkgName: com.example.ud4_propuesto_1, sendRet: true
2019-11-14 01:33:18.287 2110-12153/? D/GamePkgDataHelper: getGamePkgData(). com.example.ud4_propuesto_1
2019-11-14 01:33:18.287 2110-12153/? D/GameManagerService: handleMessage(), MSG_APP_CREATE. ignore. pkgName: com.example.ud4_propuesto_1
2019-11-14 01:33:18.289 2110-14522/? E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 598680)
2019-11-14 01:33:18.289 2110-14522/? E/ActivityManager: Second failure launching com.example.ud4_propuesto_1/.DatosCentroMandoActivity, giving up
android.os.TransactionTooLargeException: data parcel size 598680 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:1145)
at android.app.IApplicationThread$Stub$Proxy.scheduleTransaction(IApplicationThread.java:1897)
at android.app.servertransaction.ClientTransaction.schedule(ClientTransaction.java:129)
at com.android.server.am.ClientLifecycleManager.scheduleTransaction(ClientLifecycleManager.java:47)
at com.android.server.am.ActivityStackSupervisor.realStartActivityLocked(ActivityStackSupervisor.java:1862)
at com.android.server.am.ActivityStackSupervisor.attachApplicationLocked(ActivityStackSupervisor.java:1199)
at com.android.server.am.ActivityManagerService.attachApplicationLocked(ActivityManagerService.java:10029)
at com.android.server.am.ActivityManagerService.attachApplication(ActivityManagerService.java:10097)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:170)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:4162)
at android.os.Binder.execTransact(Binder.java:739)
2019-11-14 01:33:18.290 2110-14522/? I/ActivityManager: Process com.example.ud4_propuesto_1 (pid 25813) has died: fore TOP (214,2655)
附加信息
我将 Drawable
图像保存为 xxxhdpi
。
导致应用程序崩溃的项目图像大小分别为 410 KB、393 KB 和 393 KB。其余图像重量小于 345 KB。
我测试过,只有带有较重图像的项目才会导致应用程序崩溃。
问题
有什么办法可以解决吗?
Intent 总大小限制为 1MB,因此无法在其中发送位图。
您应该让您的数据对象接受从预设(可绘制资源)或图库(url 到缓存文件?)中选取的图像,然后解析它并相应地加载图像。