Estoy usando Picasso para descargar varias imágenes. Por lo general, solo los muestro en un ImageView, pero en esta situación, quiero tener una fuerte referencia a ellos para poder usarlos en diferentes lugares sin tener que consultar la caché o volver a descargarlos. Así es como estoy intentando hacer eso (tenga en cuenta que hay más en esta clase; acabo de reducirlo a las partes que son relevantes para esta pregunta):

public class MapLayer {

    private Context mContext;
    private String mType;
    private Drawable mIcon = null;

    public MapLayer (Context context, String type) {
        mContext = context;
        mType = type;
        downloadIcon();
    }

    public Drawable getIcon() {return mIcon;}

    private void downloadIcon() {

        String url = mContext.getString(R.string.maps_icon_url).replace("${type}", mType));

        Target target = new Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                Log.d(TAG, "on bitmap loaded");
                mIcon = new BitmapDrawable(mContext.getResources(), bitmap);
            }

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

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {
                Log.d(TAG, "on prepare load");
                mIcon = placeHolderDrawable;
            }
        };

        ImageDownloader.getSharedInstance().load(url).into(target);
    }
}

En todos los casos, obtengo el resultado:

on prepare load

Pero nada más. Mi icono siempre es nulo. Sé esto de otras clases donde llamo getIcon().

¿Que me estoy perdiendo aqui? Gracias por cualquier ayuda.

5
AndroidDev 27 jul. 2016 a las 18:36

2 respuestas

La mejor respuesta

Picasso tiene una instancia de Target con una referencia débil, por lo que su Target parece ser basura recolectada.
ver: https://github.com/square/picasso/issues/352

Es mejor mantener Target como campo de instancia.

public class MapLayer {

    ...

    private Target target;

    private void downloadIcon() {

        ...

        target = new Target() {
            ...
        };

        ImageDownloader.getSharedInstance().load(url).into(target);
    }
}
11
nshmura 27 jul. 2016 a las 15:53

Es porque Picasso solo mantiene una referencia débil al objeto Target.

Si desea tener una referencia sólida, le recomiendo etiquetar el Target al View.
Aquí tienes una solución para tu problema.

2
Community 23 may. 2017 a las 12:09