Android 使用毕加索从url添加标记

Android 使用毕加索从url添加标记,android,google-maps-markers,android-maps-v2,picasso,Android,Google Maps Markers,Android Maps V2,Picasso,我正在使用 因为标记不是ImageView,所以我尝试使用目标 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) {

我正在使用

因为标记不是ImageView,所以我尝试使用目标

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

        }
    }); 
}   
for(int x=0;x
我在循环中这样做是为了添加大约20个标记,但我发现在第一次运行代码时只添加了5或7个标记,所以我已经切换到使用lib和类似这样的异步任务

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();
        }
    }
}   
for(int x=0;x

然而,我有点担心这种方法会给我带来一些问题,当我有很多标记时,比如说100。我的问题是,这是最好的方法吗?如果不是,我还可以尝试其他哪些选项。

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

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


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

因此,更好的解决方案是将每个目标添加到哈希集中,然后 从目标中删除onBitmapLoaded()和onBitmapFailed方法 从集合中选择目标本身

谢谢你的建议,现在我的代码工作得很好。下面是实现您的建议的代码片段

[...]//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) {

        }
    }
[…]//全局变量
private Set poiTargets=new HashSet();
[...]    
私人空间{
POIPT目标;
用于(项目:数据){
m=map.addMarker(新的MarkerOptions()
.位置(新板条(项目纬度、项目经度))
.名称(项目名称));
pt=新目标(m);
添加(pt);
毕加索。与(上下文)
.load(mapImageURLString)
.into(pt);
}
}
[...]
//--------------------------------------------------------
//内部阶级
//--------------------------------------------------------
类PoiTarget实现目标{
专用标记m;
公共目标(标记m){this.m=m;}
@覆盖BitMapLoaded(位图位图,Picasso.LoadedFrom)上的公共空白{
m、 setIcon(BitmapDescriptorFactory.fromBitmap(位图));
删除(这个);
msg(“@+为“+m.getTitle()+”PT size:#“+poiTargets.size())设置位图;
}
@重写公共void onBitmapFailed(Drawable errorDrawable){
Tools.msg(“@+[ERROR]不为“+m.getTitle()”设置位图);
删除(这个);
}
@覆盖PrepareLoad上的公共void(可提取占位符可提取){
}
}

我将重点调试您的第一种方法。使用断点或日志语句确定无法获取标记的位置。在调用Picasso类之前,我在目标的onSuces和onError override方法中使用了日志语句。日志显示,该外观被调用了20次,OnSuces被调用了几次,onError从未调用过。杰克昨天刚刚发布了毕加索2.0.0——如果你还没有这样做的话,你可以尝试一下。否则,您可能会尝试创建一个可复制的测试用例,并将问题提交给毕加索项目。我看不出你有什么特别的问题。你的匿名
Target
可能被垃圾收集,这就是你丢失一些下载的原因。创建
mapIcon\u url.length
size的成员数组。将
目标
实例存储到阵列中。下载完成后,从阵列中删除(如果下载失败,请记住也要删除)。如果用户退出您的
活动
循环通过数组并调用
cancelRequest(数组[i])
以取消所有挂起/进行中的请求。你必须保持对你的
目标的强引用,否则它很有可能会被垃圾回收。使用毕加索2.4.0,目标会被垃圾回收。你有什么建议来修复它吗?这对毕加索2.3.2来说是可行的。我不知道h