móviles - manual de programacion android pdf
El adaptador de imagen pierde memoria (2)
La instancia de picasso que se devuelve de PicassoBuilder.build () debe ser un singleton, y cuando necesite usar picasso en toda la aplicación, debe acceder a ese singleton, en lugar de Picasso.with ... debe acceder a
YourClass.getMyPicassoSingleton().with...
De lo contrario, mantendrá cachés separados, etc. para esas instancias de Picasso
editar: como señalo a continuación, también puede llamar
picasso.setSingletonInstance(myPicasso);
justo donde invocas el método de compilación anterior, que también resolvería tu problema sin mantenerte solo. esa es probablemente una solución más limpia
Tengo una simple ListActivity que muestra imágenes e incializo mi OkHttpClient para Picasso Builder en el constructor de la clase ImageAdapter:
picassoClient = new OkHttpClient();
picassoClient.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain
.request()
.newBuilder()
.addHeader("Cookie","xyz")
.build();
return chain.proceed(newRequest);
}
});
new Picasso.Builder(context).downloader(new OkHttpDownloader(picassoClient)).build();
luego en getView()
uso Picasso para cargar imágenes en ImageView:
Picasso.with(context).load(xyzUrl).fit().centerCrop().into(vImage);
Funciona bien, pero en la rotación del dispositivo veo que el tamaño del montón a veces crece lentamente, a veces rápidamente y a veces permanece estable. Solo raramente cae. ¿Estoy perdiendo memoria o hay algo mal en el código?
EDITAR: getView()
este código después de la llamada de Picasso en getView()
if (BuildConfig.DEBUG) {
Log.i("HEAP SIZE",
String.valueOf((Runtime.getRuntime().totalMemory() / 1024)
- (Runtime.getRuntime().freeMemory() / 1024)));
}
y descubrí que el crecimiento del tamaño del montón ocurre en getView()
después de cargar el mapa de bits en ImageView. ¿Qué está mal?
EDIT 2 : intentado establecer el adaptador de imagen estático, nada cambia
EDIT 3: intentado con RecyclerView en lugar de ListView, el mismo comportamiento: el tamaño del heap crece continuamente mientras se desplaza la lista de imágenes pasando de 30 a 40 bytes en cada onBindViewHolder()
. Después de que el tamaño del montón de rotación del dispositivo crece algunas veces incluso 2-3 pasos. Rara vez se cae.
¿Por qué aumentar el tamaño de forma lenta pero continua y por qué estoy filtrando algún caché o algunos mapas de bits en caché después de la rotación del dispositivo?
ACTUALIZACIÓN: adaptador probado sin el código en el constructor (es decir, sin el new OkHttpClient
y el new Picasso.Builder
), funciona y el tamaño del new Picasso.Builder
dinámico ahora se mantiene estable . Entonces, ¿cuál es la forma correcta de inicializar al cliente con la gestión de encabezados de cookies?
UPSHOT: finalmente creé mi clase PicassoInstance, que crea un único single estático de Picasso y lo configura como singleton de la Biblioteca Picasso. Luego lo configuré en el constructor de mi adaptador
PicassoInstance.setPicassoSingleton(context);
Funciona bien, y es una forma correcta, espero.
public class PicassoInstance {
private static Picasso myPicassoInstance = null;
public static void setPicassoSingleton(Context context) {
if (myPicassoInstance == null) {
myPicassoInstance = createMyPicassoInstance(context);
Picasso.setSingletonInstance(myPicassoInstance);
if (BuildConfig.DEBUG) {
Log.i("PICASSO INSTANCE", "CREATED");
}
}
}
private static Picasso createMyPicassoInstance(Context context) {
OkHttpClient myOkHttpClient = new OkHttpClient();
myOkHttpClient.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Cookie", "xyz").build();
if (BuildConfig.DEBUG) {
Log.i("ON INTERCEPT", "COOKIE ADDED");
}
return chain.proceed(newRequest);
}
});
return new Picasso.Builder(context).downloader(
new OkHttpDownloader(myOkHttpClient)).build();
}
}
No puedo cerrarlo como demasiado amplio, pero recomiendo que hayas tomado un volcado de memoria y le hayas dado una mirada dura a Eclipse Memory Analizer Tool para encontrar las referencias que aún se mantienen vivas y por quién.
Este también es un excelente escrito sobre él .
Adaptadores como campos con fugas. Las vistas contienen un contexto que contiene vistas. Y los fragmentos son aún peores ofensores. ListActivities era una herramienta API1 que debería haber quedado obsoleta hace mucho tiempo. Todo muy propenso a fugas, pero esa es la forma de Android.