8

我正在使用Picasso 库从 url 向我的地图添加标记

由于标记不是 ImageView 我尝试使用 Target 代替

for(int x =0; x < mapIcon_url.length; x++){

    Picasso.with(getActivity()).load(mapIcon_url[x]).resize(marker_size, marker_size+15).into(new Target() {

        @Override
        public void onSuccess(Bitmap b) {
            bitmapMarker = BitmapDescriptorFactory.fromBitmap(b);


            //create marker option
            if(b != null)
                markerOptions = new MarkerOptions().position(marker_position).icon(bitmapMarker));
            else
                markerOptions = new MarkerOptions().position(marker_position).icon(BitmapDescriptorFactory.fromResource(R.drawable.placeholder_pin)).snippet(String.valueOf(x));

            marker = map.addMarker(markerOptions);                              
        }

        @Override
        public void onError() {

            //create marker option                                  
            markerOptions = new MarkerOptions().position(marker_position).icon(BitmapDescriptorFactory.fromResource(R.drawable.placeholder_pin)).snippet(String.valueOf(x));
            marker = map.addMarker(markerOptions);

        }
    }); 
}   

我在循环中执行此操作以添加大约 20 个标记,但我发现在第一次运行代码时只添加了 5 或 7 个标记,因此我已切换到使用 lib 和这样的 AsyncTask。

for(int x =0; x < mapIcon_url.length; x++){

    new AddMarker().execute(mapIcon_url[x]);
}


public class AddMarker extends AsyncTask<String, Integer, BitmapDescriptor> {

    BitmapDescriptor bitmapMarker1;
    VenueDetails myVenue;

    @Override
    protected BitmapDescriptor doInBackground(String... url) {  
        myUrl = url[0];
        try {
            bitmapMarker1 = BitmapDescriptorFactory.fromBitmap(Picasso.with(getActivity()).load(myUrl).resize(marker_size, marker_size+15).get());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bitmapMarker1;
    }

    protected void onPostExecute(BitmapDescriptor icon) {

        try {

            map.addMarker(new MarkerOptions().position(marker_position).icon(icon)));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}   

但是,当我有很多标记说大约 100 时,我有点担心这种方法会给我带来一些问题。我的问题是这是做到这一点的最佳方法,如果不是,我可以尝试哪些其他选择。

4

2 回答 2

10

您必须为每个 Target 保留一个引用,否则系统会在调用垃圾收集器时自动释放它们。

因此,更好的解决方案是将每个 Target 添加到 HashSet 中,然后在 Target 的 onBitmapLoaded() 和 onBitmapFailed 方法中,从集合中删除 Target 本身。

感谢您的建议,现在我的代码可以完美运行。在实现您的建议的代码片段下方。

[...]//Global var
  private Set<PoiTarget> poiTargets = new HashSet<PoiTarget>();
[...]    
 private void somewhere(){
    PoiTarget pt;
    for(Item item: data) {
        m = map.addMarker(new MarkerOptions()
               .position(new LatLng(item.latitude, item.longitude))
               .title(item.title));
        pt = new PoiTarget(m);
        poiTargets.add(pt);
        Picasso.with(context)
           .load(mapImageURLString)
           .into(pt);
    }
}
[...]
//--------------------------------------------------------
// Inner class
//--------------------------------------------------------
    class PoiTarget implements Target{
        private Marker m;

        public PoiTarget(Marker m) { this.m = m; }

        @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            m.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
            poiTargets.remove(this);
            Tools.msg(" @+ Set bitmap for "+m.getTitle()+" PT size: #"+poiTargets.size());
        }

        @Override public void onBitmapFailed(Drawable errorDrawable) {
            Tools.msg(" @+ [ERROR] Don't set bitmap for "+m.getTitle());
            poiTargets.remove(this);
        }

        @Override public void onPrepareLoad(Drawable placeHolderDrawable) {

        }
    }
于 2014-10-23T15:10:44.590 回答
2

您必须为每个 保留一个引用Target,否则系统会在调用垃圾收集器时自动释放它们。

因此,更好的解决方案是将每个 Target 添加到 aHashSet中,然后从 Target 中onBitmapLoaded()添加onBitmapFailed方法,从集合中删除 Target 本身。

于 2014-04-10T11:27:01.370 回答