Picasso Target已被垃圾收集

时间:2016-06-20 08:12:49

标签: android image loading

美好的一天。我有一个带有集群管理器的谷歌地图。简单的一个,我使用集群绘制分组或不分组的标记。无论如何,我从集群管理器获得了一个方法回调,它是集群项目渲染一个。在回调中我正在将自定义图像应用于标记:标记内的用户图像。我发现Picasso是最好的处理位图加载,同时让我头疼。我正在使用毕加索的Target类来启动位图回调:OnPreLoad,OnFail,OnBitmapLoaded。问题是在第一个集群项上呈现onBitmapLoaded未被调用,并且通常它永远不会被调用,除非它第二次被触摸。第一次没有任何反应,没有回调除OnPreLoad之外被触发并通过谷歌搜索我发现伟大的毕加索对该类有弱参考。我尝试了谷歌的所有例子:使目标参考强大(从方法中获得类的初始化并启动类在我的班级内,如下所示)

    @Override
protected void onClusterItemRendered(MarkerItem clusterItem, Marker marker) {
    mMarker = marker;
    mMarkerItem = clusterItem;

    Picasso.with(mContext).load(clusterItem.getImageUrl()).transform(new CircleTransformation()).into(target);
}



private Target target = new Target() {
    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        Log.d(TAG, "onBitmapLoaded: ");
    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {
        Log.d(TAG, "onBitmapFailed: ");
    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {
        Log.d(TAG, "onPrepareLoad: ");
    }
};
@Override
protected void onBeforeClusterItemRendered(MarkerItem item, MarkerOptions markerOptions) {
    markerOptions.title(item.getTitle());
    markerOptions.icon(item.getIcon());
}

此时我得到相同的结果....有时位图加载,有时不加。大多数不... 无论如何,我已经尝试将接口类实现到我自己的类中,如下所示:

public  class PicassoMarkerView implements com.squareup.picasso.Target {
private static final String TAG = "MarkerRender";
private Bitmap mMarkerBitmap;
private ClusterManager<MarkerItem> mClusterManager;
private MarkerItem mMarkerItem;
private Marker mMarker;

public PicassoMarkerView() {

}


@Override
public int hashCode() {
    return mMarker.hashCode();
}

@Override
public boolean equals(Object o) {
    if (o instanceof PicassoMarkerView) {
        Marker marker = ((PicassoMarkerView) o).mMarker;
        return mMarker.equals(marker);
    } else {
        return false;
    }
}


@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap,
            mMarkerBitmap.getWidth() - 15, (int) (mMarkerBitmap.getHeight() / 1.5 - 15),
            false);
    mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(overlay(mMarkerBitmap, scaledBitmap, 8, 7)));
    Log.d(TAG, "onBitmapLoaded: ");
}

@Override
public void onBitmapFailed(Drawable errorDrawable) {
    Log.d(TAG, "onBitmapFailed: ");
}

@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
    Log.d(TAG, "onPrepareLoad: ");
}


private Bitmap overlay(Bitmap bitmap1, Bitmap bitmap2, int left, int top) {
    Bitmap res = Bitmap.createBitmap(bitmap1.getWidth(), bitmap1.getHeight(),
            bitmap1.getConfig());

    Canvas canvas = new Canvas(res);

    canvas.drawBitmap(bitmap1, new Matrix(), null);
    canvas.drawBitmap(bitmap2, left, top, null);

    return res;
}


public void setMarkerBitmap(Bitmap markerBitmap) {
    this.mMarkerBitmap = markerBitmap;
}

public void setClusterManager(ClusterManager<MarkerItem> clusterManager) {
    this.mClusterManager = clusterManager;
}

public void setMarkerItem(MarkerItem markerItem) {
    this.mMarkerItem = markerItem;
}

public void setMarker(Marker marker) {
    this.mMarker = marker;
}

}

不幸的是,这也不起作用......结果相同......所以请亲爱的朋友们,你能给我一个这方面的工作实例吗?据我所知,问题主要发生在尝试这样做的用户身上内部循环和我的onClusterItemRender某种循环可以说,因为它是每次标记对用户可见时触发的,所以是的,它被触发了几次并且和循环一样快,所以请给我一些想法并帮助我。 ..

重要的是要提到我不需要使用毕加索的方法,例如fetch(),get(),因为它们不是必需的,也不符合应用程序的目的。

1 个答案:

答案 0 :(得分:5)

我遇到了类似的问题,并且对目标没有任何帮助。

我的项目的目的是使用2个不同的图像下载api来显示图像库,并让用户能够选择使用哪个API。

除了毕加索,我使用了格莱德,我对结果感到惊讶,格莱德的api在毕加索给我地狱的每个方面都完美无缺(这是我第一次使用格莱德,我到目前为止通常使用毕加索,似乎就像今天一样,它会改变^^)。

所以我的建议是:

  1. 使用滑翔比毕加索(目标上没有这么弱的参考)。
  2. 由于我不得不使用这两个库,我最终在处理程序中使用了get(),不确定它是否会对你有所帮助,但它解决了我的问题:
  3. handlerThread = new HandlerThread(HANDLER_THREAD_NAME);
    handlerThread.start();
    
    Handler handler = new Handler(handlerThread.getLooper());
    handler.post(new Runnable() {
        @Override
        public void run() {
            Bitmap bitmap = null;
            try {
                bitmap = picasso.with(appContext).load(url).get();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (bitmap != null) {
                    //do whatever you wanna do with the picture.
                    //for me it was using my own cache
                    imageCaching.cacheImage(imageId, bitmap);
                }
            }
        }
    });