简体   繁体   English

IllegalArgumentException:使用 gms.maps.model.Marker.setIcon 的非托管描述符

[英]IllegalArgumentException: Unmanaged descriptor using gms.maps.model.Marker.setIcon

I have an app that use android-maps-utils and glide for marker icons .我有一个使用android-maps-utils滑动标记图标的应用程序。
I got an error report using Firebase crash reporting which I can't track in source code because gms.maps.model.Marker.setIcon is private, so I'm asking for some help with this problem.我收到了一份使用 Firebase 崩溃报告的错误报告,我无法在源代码中跟踪该错误报告,因为gms.maps.model.Marker.setIcon是私有的,所以我请求帮助解决这个问题。
The follow part of the question is divided into:问题的以下部分分为:

  • What the user was doing用户在做什么
  • What firebase crash reported to me向我报告了什么 firebase 崩溃
  • Some project configs一些项目配置
  • What I tried/found trying to understand/fix it我尝试/发现试图理解/修复它

What the user was doing用户在做什么
He was zooming in and out in a map ( Fragment that uses com.google.android.gms.maps.SupportMapFragment )他正在放大和缩小地图(使用com.google.android.gms.maps.SupportMapFragment Fragment

What firebase crash reported to me向我报告了什么 firebase 崩溃

Exception java.lang.IllegalArgumentException: Unmanaged descriptor异常 java.lang.IllegalArgumentException: 非托管描述符
com.google.maps.api.android.lib6.common.kb (:com.google.android.gms.DynamiteModulesB:162) com.google.maps.api.android.lib6.common.kb (:com.google.android.gms.DynamiteModulesB:162)
com.google.maps.api.android.lib6.impl.oc (:com.google.android.gms.DynamiteModulesB:75) com.google.maps.api.android.lib6.impl.oc (:com.google.android.gms.DynamiteModulesB:75)
com.google.maps.api.android.lib6.impl.db.a (:com.google.android.gms.DynamiteModulesB:334) 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) com.google.android.gms.maps.model.internal.q.onTransact (:com.google.android.gms.DynamiteModulesB:204)
android.os.Binder.transact (Binder.java:387) 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 () 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:156)
co.com.spyspot.ui.content.sucursal.SucursalRender$CustomSimpleTarget.onResourceReady (SucursalRender.java:130) co.com.spyspot.ui.content.sucursal.SucursalRender$CustomSimpleTarget.onResourceReady (SucursalRender.java:130)
com.bumptech.glide.request.GenericRequest.onResourceReady (GenericRequest.java:525) com.bumptech.glide.request.GenericRequest.onResourceReady (GenericRequest.java:525)
com.bumptech.glide.request.GenericRequest.onResourceReady (GenericRequest.java:507) com.bumptech.glide.request.GenericRequest.onResourceReady (GenericRequest.java:507)
com.bumptech.glide.load.engine.EngineJob.handleResultOnMainThread (EngineJob.java:158) 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.access$100 (EngineJob.java:22)
com.bumptech.glide.load.engine.EngineJob$MainThreadCallback.handleMessage (EngineJob.java:202) com.bumptech.glide.load.engine.EngineJob$MainThreadCallback.handleMessage (EngineJob.java:202)
android.os.Handler.dispatchMessage (Handler.java:98) android.os.Handler.dispatchMessage (Handler.java:98)
android.os.Looper.loop (Looper.java:148) android.os.Looper.loop (Looper.java:148)
android.app.ActivityThread.main (ActivityThread.java:5443) android.app.ActivityThread.main (ActivityThread.java:5443)
java.lang.reflect.Method.invoke (Method.java) java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:728) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:728)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:618) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:618)

And:和:

在此处输入图片说明

Some project configs一些项目配置

  • I'm using a Custom Render ( SucursalRender extends DefaultClusterRenderer<Sucursal> )我正在使用自定义渲染( SucursalRender extends DefaultClusterRenderer<Sucursal>
  • I'm downloading the Marker icon with Glide like I said before: Glide.with(context).load(id).fitCenter().placeholder(R.drawable.ic_no_image).into(simpleTarget);我正在下载带有 Glide 的标记图标,就像我之前说的: Glide.with(context).load(id).fitCenter().placeholder(R.drawable.ic_no_image).into(simpleTarget);

The simpleTarget is where I handle the images downloaded/cached for Glide. simpleTarget是我处理为 Glide 下载/缓存的图像的地方。 I'm posting all code about simpleTarget because the crash is starting there:我发布了关于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));
        }
    }
}

The crash is being thrown in last line of code: markerToChange.setIcon(BitmapDescriptorFactory.fromBitmap(icon));崩溃是在最后一行代码中抛出的: markerToChange.setIcon(BitmapDescriptorFactory.fromBitmap(icon));

What I tried/found trying to understand/fix it我尝试/发现试图理解/修复它

  • Tried to reproduce the error in 4 real devices without success.尝试在 4 台真实设备中重现该错误,但未成功。
  • Searched in web for similar errors or code about gms.maps.model.Marker.setIcon or com.google.maps.api.android.lib6在网上搜索有关gms.maps.model.Marker.setIconcom.google.maps.api.android.lib6类似错误或代码
  • Tried to understand the obfuscated code given in Android Studio for Marker.setIcon试图理解 Android Studio 中为Marker.setIcon提供的混淆代码

I guess I can wrap the code in a try-catch block for that IllegalArgumentException: Unmanaged descriptor to avoid application get closed because the crash but it's just a work around it.我想我可以将代码包装在 IllegalArgumentException: Unmanaged descriptor 的try-catch block中,以避免应用程序因为崩溃而关闭,但这只是一个解决方法。

update 2更新 2
The code of DefaultClusterRenderer : DefaultClusterRenderer的代码:

public class SucursalRender extends DefaultClusterRenderer<Sucursal> {
    /**
     * Create a customized icon for markers with two background colors. Used with {@link com.google.maps.android.clustering.ClusterItem}.
     */
    private final CustomIconGenerator mIconGenerator;
    /**
     * Marker image.
     */
    private final ImageView mImageView;
    /**
     * Create a customized icon for {@link Cluster<Sucursal>} with a single background.
     */
    private final IconGenerator mClusterIconGenerator;
    /**
     * Cluster image.
     */
    private final ImageView mClusterImageView;
    private final Context mContext;
    /**
     * Keep a reference to the current item highlighted in UI (the one with different background).
     */
    public Sucursal currentSelectedItem;
    /**
     * The {@link ClusterManager<Sucursal>} instance.
     */
    private ClusterManager<Sucursal> mClusterManager;

    public SucursalRender(Context context, GoogleMap map, ClusterManager<Sucursal> clusterManager) {
        super(context, map, clusterManager);

        mContext = context;
        mClusterManager = clusterManager;
        mIconGenerator = new CustomIconGenerator(mContext.getApplicationContext());
        mClusterIconGenerator = new IconGenerator(mContext.getApplicationContext());

        int padding = (int) mContext.getResources().getDimension(R.dimen.custom_profile_padding);
        int dimension = (int) mContext.getResources().getDimension(R.dimen.custom_profile_image);

        //R.layout.map_cluster_layout is a simple XML with the visual elements to use in markers and cluster
        View view = ((AppCompatActivity)mContext).getLayoutInflater().inflate(R.layout.map_cluster_layout, null);
        mClusterIconGenerator.setContentView(view);
        mClusterImageView = (ImageView) view.findViewById(R.id.image);
        mClusterImageView.setPadding(padding, padding, padding, padding);

        mImageView = new ImageView(mContext.getApplicationContext());
        mImageView.setLayoutParams(new ViewGroup.LayoutParams(dimension, dimension));
        mImageView.setPadding(padding, padding, padding, padding);
        mIconGenerator.setContentView(mImageView);

        CustomIconBackground customIconBackground = new CustomIconBackground(false);
        mIconGenerator.setBackground(customIconBackground);
        mIconGenerator.customIconBackground = customIconBackground;
        mClusterIconGenerator.setBackground(new CustomIconBackground(true));
    }

    ...

    @Override
    protected void onBeforeClusterItemRendered(final Sucursal sucursal, MarkerOptions markerOptions) {

        mImageView.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_no_image));
        Bitmap icon = mIconGenerator.makeIcon();
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
    }

    @Override
    protected void onClusterItemRendered(Sucursal clusterItem, Marker marker) {
        CustomSimpleTarget simpleTarget = new CustomSimpleTarget();
        simpleTarget.sucursal = clusterItem;
        simpleTarget.markerToChange = marker;
        ImageLoaderManager.setImageFromId(simpleTarget, clusterItem.logo, mContext);
    }

    @Override
    protected void onBeforeClusterRendered(Cluster<Sucursal> cluster, MarkerOptions markerOptions) {
        mClusterImageView.setImageDrawable(ResourcesCompat.getDrawable(mContext.getResources(), R.drawable.ic_sucursales, null));
        Bitmap icon = mClusterIconGenerator.makeIcon(String.valueOf(cluster.getSize()));
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
    }

    @Override
    protected boolean shouldRenderAsCluster(Cluster cluster) {
        // Always render clusters.
        return cluster.getSize() > 1;
    }

    /**
     * Just extends {@link IconGenerator} and give the ability to change background.
     * Used to know highlight the current selected item in UI.
     */
    private class CustomIconGenerator extends IconGenerator {
        private CustomIconBackground customIconBackground;
        private CustomIconGenerator(Context context) {
            super(context);
        }
    }


    /**
     * Create a custom icon to use with {@link Marker} or {@link Cluster<Sucursal>}
     */
    private class CustomIconBackground  extends Drawable {

        private final Drawable mShadow;
        private final Drawable mMask;
        private int mColor = Color.WHITE;

        private boolean useSelectionColor;
        private int mColorSelection;

        private CustomIconBackground(boolean isCluster) {
            useSelectionColor = false;

            if (isCluster) {
                mMask = ContextCompat.getDrawable(mContext, R.drawable.map_pin_negro_cluster);
                mShadow = ContextCompat.getDrawable(mContext, R.drawable.map_pin_transparente_cluster);
            }
            else {
                mMask = ContextCompat.getDrawable(mContext, R.drawable.map_pin_negro);
                mShadow = ContextCompat.getDrawable(mContext, R.drawable.map_pin_transparente);
            }
        }

        public void setColor(int color) {
            mColor = color;
        }

        private void useSelectionColor(boolean value, int color) {
            useSelectionColor = value;
            mColorSelection = color;
        }
        @Override
        public void draw(@NonNull Canvas canvas) {
            mMask.draw(canvas);
            canvas.drawColor(mColor, PorterDuff.Mode.SRC_IN);
            mShadow.draw(canvas);

            if (useSelectionColor) {
                canvas.drawColor(mColorSelection, PorterDuff.Mode.SRC_IN);
                useSelectionColor = false;
            }
        }

        @Override
        public void setAlpha(int alpha) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
            throw new UnsupportedOperationException();
        }

        @Override
        public int getOpacity() {
            return PixelFormat.TRANSLUCENT;
        }

        @Override
        public void setBounds(int left, int top, int right, int bottom) {
            mMask.setBounds(left, top, right, bottom);
            mShadow.setBounds(left, top, right, bottom);
        }

        @Override
        public void setBounds(@NonNull Rect bounds) {
            mMask.setBounds(bounds);
            mShadow.setBounds(bounds);
        }

        @Override
        public boolean getPadding(@NonNull Rect padding) {
            return mMask.getPadding(padding);
        }
    }

The ImageLoaderManager is just a Facade for Glide. ImageLoaderManager只是 Glide 的 Facade。

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);
}

When clearing the map with清除地图时

    googleMap.clear();

**remove any reference to all the markers** on the map. **remove any reference to all the markers**对地图上**remove any reference to all the markers** I had the problem and figured out that the problem was with my code which I forgot to remove reference to a marker and tried to change icon of a cleared Marker我遇到了问题并发现问题出在我的代码上,我忘记删除对标记的引用并尝试更改已cleared Marker图标

I found this happening when accessing marker after it was removed.我发现在删除标记后访问标记时会发生这种情况。 Interacting with marker in callback is exactly that case.在回调中与标记交互就是这种情况。 As mentioned in Map's API:正如 Map 的 API 中提到的:

After a marker has been removed, the behavior of all its methods is undefined.删除标记后,其所有方法的行为都未定义。 https://developers.google.com/android/reference/com/google/android/gms/maps/model/Marker.html#remove() https://developers.google.com/android/reference/com/google/android/gms/maps/model/Marker.html#remove()

Best option would be checking is marker removed from map or not.最好的选择是检查标记是否从地图中删除。
But we don't have such API.但是我们没有这样的API。 And I found another workaround, we can use Marker's setTag and getTag .我找到了另一种解决方法,我们可以使用 Marker 的setTaggetTag Tag is set to null, when marker is removed:当标记被移除时,标记被设置为空:

Google Maps Android API neither reads nor writes this property, except that when a marker is removed from the map, this property is set to null. Google Maps Android API 既不读取也不写入此属性,除非从地图中删除标记时,此属性设置为 null。 https://developers.google.com/android/reference/com/google/android/gms/maps/model/Marker.html#setTag(java.lang.Object) https://developers.google.com/android/reference/com/google/android/gms/maps/model/Marker.html#setTag(java.lang.Object)

When creating marker use some tag for it.创建标记时,请为其使用一些标签。
When updating marker check tag is not null.更新标记时检查标签不为空。

This could help in your case.这可能对您的情况有所帮助。

@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);
}

And in callback在回调中

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));
            }
        }
    }
}

I was too getting same exception and setting silent exception with try/catch would not have been solution as user is not able to see current location in my case:我也遇到了同样的异常,并且使用 try/catch 设置静默异常不会成为解决方案,因为在我的情况下,用户无法看到当前位置:

java.lang.IllegalArgumentException: Unmanaged descriptor at com.google.maps.api.android.lib6.common.kb(:com.google.android.gms.DynamiteModulesB:162) at com.google.maps.api.android.lib6.impl.oc(:com.google.android.gms.DynamiteModulesB:75) at com.google.maps.api.android.lib6.impl.db.a(:com.google.android.gms.DynamiteModulesB:334) at com.google.android.gms.maps.model.internal.q.onTransact(:com.google.android.gms.DynamiteModulesB:204) at android.os.Binder.transact(Binder.java:361) at com.google.android.gms.maps.model.internal.zzf$zza$zza.zzL(Unknown Source) at com.google.android.gms.maps.model.Marker.setIcon(Unknown Source) java.lang.IllegalArgumentException:com.google.maps.api.android.lib6.common.kb(:com.google.android.gms.DynamiteModulesB:162) 上的非托管描述符,位于 com.google.maps.api.android.lib6 .impl.oc(: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(来源不明)

What I was doing :我在做什么:

Minimize the map fragment screen by pressing home button and then starting app from launcher.通过按主页按钮然后从启动器启动应用程序来最小化地图片段屏幕。

What code was doing:代码在做什么:

Checking is marker is not null and location is not null set location and icon.检查标记不为空和位置不为空设置位置和图标。

     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);
                }       
         }

Exception was at : markerCurrentLocation.setIcon();异常在:markerCurrentLocation.setIcon();

How I got rid of this exception:我如何摆脱这个异常:

I removed the following line我删除了以下行

 if (markerCurrentLocation == null && googleMap != null) 

Which means I am initializing marker again.这意味着我再次初始化标记。 If you encounter this error, try not to setIcon() on old marker, instead inflate new marker and then use setIcon().如果遇到此错误,请尽量不要在旧标记上使用 setIcon(),而是先膨胀新标记,然后再使用 setIcon()。

Explanation:解释:

I ASSUME (not sure) exception reason was if code is trying to setIcon() again on marker on which it is already set , at particular instance like in my case Map is resuming or may be in your case marker goes out of visible part of map and comes in or something similar.我假设(不确定)异常原因是,如果代码试图在已经设置的标记上再次 setIcon() ,在特定情况下,例如在我的情况下 Map 正在恢复或可能在您的情况下标记超出可见部分地图和进来或类似的东西。

For sure there is no problem with descriptor we get from method BitmapDescriptorFactory.fromBitmap() or BitmapDescriptorFactory.fromResource().可以肯定的是,我们从方法 BitmapDescriptorFactory.fromBitmap() 或 BitmapDescriptorFactory.fromResource() 获得的描述符没有问题。 As the exception hints, descriptor got unmanaged on a old marker, better use new one.作为异常提示,描述符在旧标记上不受管理,最好使用新标记。

This exception happens when your marker was reclustered by ClusterManager .当您的标记被ClusterManager重新集群时,会发生此异常。 ClusterManager recreates marker on clustering. ClusterManager在集群上重新创建标记。 So, to avoid it you must get your marker from render of ClusterManeger :因此,为了避免它,您必须从ClusterManeger渲染中获取标记:

ClusterIconRender render = (ClusterIconRender) mClusterManager.getRenderer();
Marker trueMarker = render.getMarker(clusterMarker);
if (trueMarker != null) {
    trueMarker.setIcon(...);
    ... // do whatever else your want with marker
}

In code above ClusterMarker implements ClusterItem and ClusterIconRender extends DefaultClusterRenderer .在上面的代码中ClusterMarker实现了ClusterItemClusterIconRender扩展了DefaultClusterRenderer

I have the same environment (maps-utils + custom renderer + Glide) and the same error IllegalArgumentException: Unmanaged descriptor .我有相同的环境(maps-utils + 自定义渲染器 + Glide)和相同的错误IllegalArgumentException: Unmanaged descriptor

I solved the error by checking if the marker is "valid" before setting the icon, using the methods DefaultClusterRenderer.getCluster(Marker) and DefaultClusterRenderer.getClusterItem(Marker) .我使用DefaultClusterRenderer.getCluster(Marker)DefaultClusterRenderer.getClusterItem(Marker)方法,通过在设置图标之前检查标记是否“有效”来解决该错误。 If both return null , I don't do anything on the onResourceReady(...) method.如果两者都返回null ,我不会对onResourceReady(...)方法做任何事情。

In your case I would try the following change to CustomSimpleTarget :在您的情况下,我会尝试对CustomSimpleTarget进行以下更改:

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));
        }
    }
}

PS.: I can reproduce the problem easily on a slow device and clearing the app cache before testing (to force Glide to load from network). PS.:我可以在较慢的设备上轻松重现该问题并在测试前清除应用程序缓存(以强制 Glide 从网络加载)。 Then I open the map and perform some zoom in/out before any markers load.然后我打开地图并在加载任何标记之前执行一些放大/缩小。

Had the same exception after adding cluster.添加集群后出现同样的异常。 I fixed it by calling:我通过调用修复它:

clusterManager.clearItems()

Instead of calling method I used before, without cluster:而不是我之前使用的调用方法,没有集群:

googleMap.clear();

确保您用于标记的图标不应该是矢量,它应该是 .png 图像。

I fixed it by calling the following method.我通过调用以下方法修复了它。

clusterManager.clearItems()

After that, you can set bitmap to the markers.之后,您可以将位图设置为标记。

Marker centerPoint标记中心点

when you do that: centerPoint.remove();当你这样做时: centerPoint.remove();

And then you do it again :然后你再做一次:

marker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));

It throws an error :它抛出一个错误:

Unmanaged descriptor非托管描述符

You should centerPoint.remove(); centerPoint=null;你应该centerPoint.remove(); centerPoint=null; centerPoint.remove(); centerPoint=null;

Try试试

mClusterManager.markerCollection.clear();
mMap.clear()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 IllegalArgumentException:非托管描述符 - IllegalArgumentException: Unmanaged descriptor 如何在Android上的GoogleMap中修复com.google.android.gms.maps.model.Marker com.google.android.gms.maps.GoogleMap.addMarker - How to fix com.google.android.gms.maps.model.Marker com.google.android.gms.maps.GoogleMap.addMarker in GoogleMap on Android Google Maps错误尝试调用&#39;com.google.android.gms.maps.model.Marker - Google Maps Error trying to invoke 'com.google.android.gms.maps.model.Marker 使用 map.clear() 的非托管描述符异常 - Unmanaged descriptor exception using map.clear() 包com.google.android.gms.maps.model不存在 - package com.google.android.gms.maps.model does not exist Android-marker.setIcon()的空引用 - Android - Null Reference for marker.setIcon() com.google.android.gms.maps.GoogleMap.addMarker(com.google.android.gms.maps.model.MarkerOptions)”上的空对象引用 - com.google.android.gms.maps.GoogleMap.addMarker(com.google.android.gms.maps.model.MarkerOptions)' on a null object reference java.lang.IllegalArgumentException:二进制XML文件第7行:带有com.google.android.gms.maps.MapFragment的另一个片段 - java.lang.IllegalArgumentException: Binary XML file line #7: with another fragment for com.google.android.gms.maps.MapFragment Android Google Maps使用GeoJSON设置标记 - Android Google Maps set marker using GeoJSON 使用GeoJson将标记添加到Google地图 - Add marker to google maps by using GeoJson
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM