Na minha função:
public void getPointMarkerFromUrl(final String url, final OnBitmapDescriptorRetrievedListener listener) {
final int maxSize = context.getResources().getDimensionPixelSize(R.dimen.icon_max_size);
Target t = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
if (bitmap != null)
listener.bitmapRetrieved(getBitmapDescriptorInCache(url, bitmap));
else
loadDefaultMarker(listener);
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
loadDefaultMarker(listener);
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
Picasso.with(context)
.load(url)
.resize(maxSize, maxSize)
.into(t);
}
O onBitmapLoaded () nunca é chamado na primeira vez que carrego imagens. Eu li alguns tópicos como https://github.com/square/picasso/issues/39 que recomendam usar o método fetch (Target t) (parece ser um problema de referência fraca ...), mas essa função não está disponível na última versão do picasso (2.3.2). Eu tenho apenas um método fetch (), mas não posso usar o (mytarget) ao mesmo tempo
Você poderia me explicar como usar fetch () com um Target personalizado, por favor? Obrigado.
Doc: http://square.github.io/picasso/javadoc/com/squareup/picasso/RequestCreator.html#fetch--
Respostas:
Conforme observado pelos outros entrevistados (@lukas e @mradzinski), Picasso mantém apenas uma referência fraca ao
Target
objeto. Embora você possa armazenar uma referência forteTarget
em uma de suas aulas, isso ainda pode ser problemático se asTarget
referências forem deView
alguma maneira, já que você também manterá uma forte referência a elaView
(o que é uma das coisas que Picasso explicitamente ajuda a evitar).Se você estiver nessa situação, recomendo marcar a opção
Target
comoView
:Essa abordagem tem o benefício de deixar o Picasso cuidar de tudo para você. Ele gerenciará os
WeakReference
objetos para cada uma das suas visualizações - assim que uma não for mais necessária, oTarget
processamento da imagem também será liberado, para que você não fique preso a vazamentos de memória devido a alvos de longa duração, mas seu Target durará enquanto sua visão estiver viva.fonte
O Picasso não possui uma forte referência ao objeto Target, portanto, está sendo coletado como lixo e
onBitmapLoaded
não é chamado.A solução é bastante simples, basta fazer uma forte referência ao
Target
.fonte
View
implementoTarget
.Object.equals(Object)
eObject.hashCode()
métodos. você tem uma amostra de trabalho?Se eu tivesse o ImageView, simplesmente faria assim: imageView.setTag (target);
Eu uso a próxima solução para carregar Bitmaps nas notificações, portanto, preciso apenas de bitmap.
Então, criar Set irá armazenar objetos de destino e removê-los no final do carregamento.
fonte
fonte
Aqui está a solução para aqueles que não estão usando uma exibição. Este método auxiliar usa uma lista para armazenar temporariamente o objeto de destino até que um resultado seja retornado, de forma que não seja gc'd:
fonte
Como @lukas disse (e citou), Picasso não possui uma forte referência ao objeto Target. Para evitar a coleta de lixo, você deve manter uma forte referência ao objeto.
Sobre o método fetch (). É bem claro na documentação que fetch () não deve ser usado com um ImageView nem com um Target, é apenas para "aquecer" o cache e nada mais, para que você não possa usá-lo da maneira que deseja. quer.
Eu recomendo que você mantenha uma referência forte como o @lukas explicou, ele deve funcionar. Caso contrário, abra um novo problema na página GitHub do projeto.
fonte
Encontrei um problema semelhante e manter a referência ao destino não ajudou em nada, então usei o seguinte código que retorna um Bitmap:
no lado inferior -> não há retorno de chamada e você não pode chamar esta função no encadeamento principal, você deve executar esta função em um encadeamento em segundo plano, como no exemplo a seguir:
Outra coisa que funciona muito melhor é apenas usar o Glide!
Eu precisava usar os dois, pois o objetivo do meu projeto era usar 2 APIs de download de imagens diferentes para mostrar uma galeria de imagens e dar ao usuário a capacidade de escolher qual API usar.
Devo dizer que fiquei impressionado com os resultados, a API de Glide funcionou perfeitamente em todos os aspectos (o alvo de Glide não tem referência fraca), enquanto Picasso me deu um inferno (essa foi a primeira vez que usei o Glide, eu costumava usar Picasso até agora, Parece que hoje vai mudar ^^).
fonte
Eu já havia enfrentado o mesmo problema, mas quando alterei a dependência, conforme mencionado abaixo, ele funciona corretamente agora.
fonte