Android IllegalArgumentException:使用gms.maps.model.Marker.setIcon的非托管描述符
我有一个使用和的应用程序。Android IllegalArgumentException:使用gms.maps.model.Marker.setIcon的非托管描述符,android,google-maps,android-glide,android-maps-utils,Android,Google Maps,Android Glide,Android Maps Utils,我有一个使用和的应用程序。 我得到了一个使用Firebase崩溃报告的错误报告,我无法在源代码中跟踪该报告,因为gms.maps.model.Marker.setIcon是私有的,所以我请求对此问题提供一些帮助。 问题的以下部分分为: 用户在做什么 firebase坠毁事件向我报告了什么 某些项目配置 我试图理解/修复它的内容/发现 用户正在做什么 他在地图中放大缩小(Fragment,使用com.google.android.gms.maps.SupportMapFragment) fi
我得到了一个使用Firebase崩溃报告的错误报告,我无法在源代码中跟踪该报告,因为
gms.maps.model.Marker.setIcon
是私有的,所以我请求对此问题提供一些帮助。问题的以下部分分为:
- 用户在做什么
- firebase坠毁事件向我报告了什么
- 某些项目配置
- 我试图理解/修复它的内容/发现
他在地图中放大缩小(
Fragment
,使用com.google.android.gms.maps.SupportMapFragment
)
firebase坠毁事件向我报告了什么
异常java.lang.IllegalArgumentException:非托管描述符
com.google.maps.api.android.lib6.common.k.b(:com.google.android.gms.DynamiteModulesB:162)
com.google.maps.api.android.lib6.impl.o.c(:com.google.android.gms.DynamiteModulesB:75)
com.google.maps.api.android.lib6.impl.db.a(:com.google.android.gms.DynamiteModulesB:334)
com.google.android.gms.maps.model.internal.q.onTransact(:com.google.android.gms.DynamiteModulesB:204)
android.os.Binder.transact(Binder.java:387)
com.google.android.gms.maps.model.internal.zzf$zza$zza.zzL() com.google.android.gms.maps.model.Marker.setIcon()
co.com.spyspot.ui.content.sucursal.SucursalRender$CustomSimpleTarget.onResourceReady(SucursalRender.java:156)
co.com.spyspot.ui.content.sucursal.SucursalRender$CustomSimpleTarget.onResourceReady(SucursalRender.java:130)
com.bumptech.glide.request.generirequest.onResourceReady(generirequest.java:525)
com.bumptech.glide.request.generirequest.onResourceReady(generirequest.java:507)
com.bumptech.glide.load.engine.EngineJob.handleResultOnMainThread(EngineJob.java:158)
com.bumptech.glide.load.engine.EngineJob.access$100(EngineJob.java:22)
com.bumptech.glide.load.engine.EngineJob$MainThreadCallback.handleMessage(EngineJob.java:202)
android.os.Handler.dispatchMessage(Handler.java:98)
android.os.Looper.loop(Looper.java:148)
android.app.ActivityThread.main(ActivityThread.java:5443)
java.lang.reflect.Method.invoke(Method.java)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 和:
某些项目配置
- 我正在使用自定义渲染(
)SucursalRender扩展了DefaultClusterRenderer
- 我正在用Glide下载标记图标,就像我之前说过的:
Glide.with(context.load(id).fitCenter().placeholder(R.drawable.ic_no_image).into(simpleTarget)代码>
simpleTarget
是我处理为Glide下载/缓存的图像的地方。我正在发布所有关于simpleTarget
的代码,因为崩溃从那里开始:private class CustomSimpleTarget extends SimpleTarget<GlideDrawable> {
Sucursal sucursal;
Marker markerToChange = null;
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
mImageView.setImageDrawable(resource);
//currentSelectedItem is the current element selected in the map (Sucursal type)
//mIconGenerator is a: CustomIconGenerator extends IconGenerator
if (currentSelectedItem != null && sucursal.idalmacen.contentEquals(currentSelectedItem.idalmacen))
mIconGenerator.customIconBackground.useSelectionColor(true, ContextCompat.getColor(mContext, R.color.colorAccent));
else
mIconGenerator.customIconBackground.useSelectionColor(false, 0);
Bitmap icon = mIconGenerator.makeIcon();
if (markerToChange == null) {
for (Marker marker : mClusterManager.getMarkerCollection().getMarkers()) {
if (marker.getPosition().equals(sucursal.getPosition())) {
markerToChange = marker;
}
}
}
// if found - change icon
if (markerToChange != null) {
//GlideShortcutDrawable is a WeakReference<>(drawable)
sucursal.setGlideShortCutDrawable(resource);
markerToChange.setIcon(BitmapDescriptorFactory.fromBitmap(icon));
}
}
}
ImageLoaderManager
只是Glide的一个门面
public static void setImageFromId(SimpleTarget<GlideDrawable> simpleTarget, String id, Context context) {
if (context instanceof AppCompatActivity) {
AppCompatActivity activity = (AppCompatActivity)context;
if (activity.isDestroyed())
return;
}
Glide.with(context)
.load(id)
.fitCenter()
.placeholder(R.drawable.ic_no_image)
.into(simpleTarget);
}
公共静态void setImageFromId(SimpleTarget SimpleTarget,字符串id,上下文){
if(AppCompatActivity的上下文实例){
AppCompatActivity活动=(AppCompatActivity)上下文;
if(activity.isDestroyed())
返回;
}
带(上下文)滑动
.负载(id)
.fitCenter()
.占位符(R.drawable.ic\u编号\u图像)
.进入(单纯形);
}
确保用于标记的图标不应为矢量,而应为.png图像 我也遇到了同样的异常,使用try/catch设置静默异常将不是解决方案,因为在我的情况下,用户无法看到当前位置:
java.lang.IllegalArgumentException:非托管描述符
位于com.google.maps.api.android.lib6.common.k.b(:com.google.android.gms.DynamiteModulesB:162)
位于com.google.maps.api.android.lib6.impl.o.c(:com.google.android.gms.DynamiteModulesB:75)
位于com.google.maps.api.android.lib6.impl.db.a(:com.google.android.gms.DynamiteModulesB:334)
位于com.google.android.gms.maps.model.internal.q.onTransact(:com.google.android.gms.DynamiteModulesB:204)
位于android.os.Binder.transact(Binder.java:361)
位于com.google.android.gms.maps.model.internal.zzf$zza$zza.zzL(未知
(来源)
位于com.google.android.gms.maps.model.Marker.setIcon(未知来源)
我在做什么:
按home按钮,然后从launcher启动应用程序,最小化地图碎片屏幕
代码在做什么:
检查标记是否为非空,位置是否为非空,设置位置和图标
if (markerCurrentLocation == null && googleMap != null) {
markerCurrentLocation = googleMap.addMarker(new MarkerOptions()
.position(new LatLng(0.0, 0.0))
.icon(null));
markerCurrentLocation.setTag(-101);
}
if (markerCurrentLocation != null && location != null) {
markerCurrentLocation.setPosition(new LatLng(location.getLatitude(), location.getLongitude()));
if (ORDER_STARTED) {
markerCurrentLocation.setIcon(CURRENT_MARKER_ORANGE);
} else {
markerCurrentLocation.setIcon(CURRENT_MARKER_GRAY);
}
}
异常位于:markerCurrentLocation.setIcon()
我是如何摆脱这个异常的:
我删除了下面的一行
if (markerCurrentLocation == null && googleMap != null)
这意味着我再次初始化标记。
如果遇到此错误,请尝试不要在旧标记上设置图标(),而是将新标记充气,然后使用设置图标()
说明:
我假设(不确定)异常的原因是,如果代码试图在已经设置了图标的标记上再次设置图标(),在特定的情况下,例如在我的示例中,映射正在恢复,或者在您的示例中,标记从映射的可见部分消失并进入或类似的内容
确保从方法BitmapDescriptorFactory.fromBitmap()或
BitmapDescriptorFactory.fromResource()。
作为异常提示,描述符在旧标记上处于非托管状态,最好使用新标记 我有相同的环境(映射utils+自定义渲染器+Glide)和相同的错误
IllegalArgumentException:Unmanaged descriptor
在设置图标之前,我使用方法DefaultClusterRenderer.getCluster(marker)
和Defa检查标记是否“有效”,从而解决了这个错误
if (markerCurrentLocation == null && googleMap != null)
private class CustomSimpleTarget extends SimpleTarget<GlideDrawable> {
Sucursal sucursal;
Marker markerToChange = null;
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
if (getCluster(markerToChange) != null || getClusterItem(markerToChange) != null) {
mImageView.setImageDrawable(resource);
//currentSelectedItem is the current element selected in the map (Sucursal type)
//mIconGenerator is a: CustomIconGenerator extends IconGenerator
if (currentSelectedItem != null && sucursal.idalmacen.contentEquals(currentSelectedItem.idalmacen))
mIconGenerator.customIconBackground.useSelectionColor(true, ContextCompat.getColor(mContext, R.color.colorAccent));
else
mIconGenerator.customIconBackground.useSelectionColor(false, 0);
Bitmap icon = mIconGenerator.makeIcon();
//GlideShortcutDrawable is a WeakReference<>(drawable)
sucursal.setGlideShortCutDrawable(resource);
markerToChange.setIcon(BitmapDescriptorFactory.fromBitmap(icon));
}
}
}
@Override
protected void onClusterItemRendered(Sucursal clusterItem, Marker marker) {
// we don't care about tag's type so don't reset original one
if (marker.getTag() == null) {
marker.setTag("anything");
}
CustomSimpleTarget simpleTarget = new CustomSimpleTarget();
simpleTarget.sucursal = clusterItem;
simpleTarget.markerToChange = marker;
ImageLoaderManager.setImageFromId(simpleTarget, clusterItem.logo, mContext);
}
private class CustomSimpleTarget extends SimpleTarget<GlideDrawable> {
...
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
...
// if found - change icon
if (markerToChange != null) {
//GlideShortcutDrawable is a WeakReference<>(drawable)
sucursal.setGlideShortCutDrawable(resource);
if (markerToChange.getTag != null) {
markerToChange.setIcon(BitmapDescriptorFactory.fromBitmap(icon));
}
}
}
}
ClusterIconRender render = (ClusterIconRender) mClusterManager.getRenderer();
Marker trueMarker = render.getMarker(clusterMarker);
if (trueMarker != null) {
trueMarker.setIcon(...);
... // do whatever else your want with marker
}
googleMap.clear();
clusterManager.clearItems()
mClusterManager.markerCollection.clear();
mMap.clear()
clusterManager.clearItems()
googleMap.clear();