如何从URL加载图片到Google Maps标记?解决‘Image buffer is not an array’错误
解决Google Maps Marker加载网络图片时的“Image buffer is not an array”错误
兄弟,你踩了异步加载的经典坑!咱们先把问题根源说清楚:
你写的getBitmapFromURL方法里,Glide加载图片是异步操作——它会在后台线程完成下载、解码图片的工作,但你调用完Glide之后立刻就return bitmap,这时候Glide还没来得及给bitmap赋值,返回的其实是null!Google Maps的Marker拿到null的Bitmap,自然就抛出了Image buffer is not an array这个错误。
接下来给你两个靠谱的实现方案,都是围绕Glide的异步特性调整的:
方案一:先添加Marker,再异步更新图标
先创建带默认图标的Marker,等Glide加载完图片后再替换图标,这样用户能先看到Marker,加载完成后再显示自定义图标,体验更流畅:
// 1. 先添加带默认图标的Marker占位 Marker marker = mGoogleMap.addMarker(new MarkerOptions() .position(new LatLng(latitude, longitude)) .anchor(0.5f, 0.5f) .title(title) .snippet(snippet) .icon(BitmapDescriptorFactory.defaultMarker())); // 2. 用Glide异步加载图片,完成后更新Marker图标 Glide.with(this) .asBitmap() .load("https://c.ndtvimg.com/2019-10/5cnigl7_virat-kohli-afp_625x300_15_October_19.jpg") .placeholder(R.drawable.loading_marker) // 可选:加载中显示的占位图 .error(R.drawable.error_marker) // 可选:加载失败时显示的错误图 .into(new CustomTarget<Bitmap>(25,25) { @Override public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) { // 把加载好的Bitmap转成Marker需要的BitmapDescriptor BitmapDescriptor customIcon = BitmapDescriptorFactory.fromBitmap(resource); marker.setIcon(customIcon); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { // 加载被清除时(比如页面销毁),把图标改回默认 marker.setIcon(BitmapDescriptorFactory.defaultMarker()); } });
方案二:等图片加载完成后再创建Marker
如果必须要等图片加载完成才显示Marker,可以封装一个方法,在Glide的onResourceReady回调里再创建Marker:
// 封装加载+创建Marker的方法 private void createMarkerWithCustomIcon(double latitude, double longitude, String title, String snippet, String imageUrl) { Glide.with(this) .asBitmap() .load(imageUrl) .placeholder(R.drawable.loading_marker) .error(R.drawable.error_marker) .into(new CustomTarget<Bitmap>(25,25) { @Override public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) { BitmapDescriptor customIcon = BitmapDescriptorFactory.fromBitmap(resource); // 图片加载完成后,创建并添加Marker mGoogleMap.addMarker(new MarkerOptions() .position(new LatLng(latitude, longitude)) .anchor(0.5f, 0.5f) .title(title) .snippet(snippet) .icon(customIcon)); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { // 加载失败/清除时,用默认图标创建Marker mGoogleMap.addMarker(new MarkerOptions() .position(new LatLng(latitude, longitude)) .anchor(0.5f, 0.5f) .title(title) .snippet(snippet) .icon(BitmapDescriptorFactory.defaultMarker())); } }); } // 调用方法,传入参数 createMarkerWithCustomIcon(latitude, longitude, title, snippet, "https://c.ndtvimg.com/2019-10/5cnigl7_virat-kohli-afp_625x300_15_October_19.jpg");
额外优化建议
- 利用Glide的缓存机制:Glide默认会缓存网络图片,多次加载同一个URL不会重复下载,节省流量和时间
- 控制Bitmap尺寸:你设置的25x25已经很小了,Glide会自动按这个尺寸缩放图片,避免内存溢出
- 处理异常情况:加上
error()和placeholder(),让加载状态更友好,不会让用户看到空白或生硬的错误提示
内容的提问来源于stack exchange,提问作者Prateek Gupta
相关产品推荐
相关产品推荐

