У меня есть простая ListActivity, которая показывает изображения, и я инициализирую свой OkHttpClient для Picasso Builder в конструкторе класса 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();
затем в getView()
я использую Picasso для загрузки изображений в ImageView:
Picasso.with(context).load(xyzUrl).fit().centerCrop().into(vImage);
Это хорошо работает, но при вращении устройства я вижу, что размер кучи иногда медленно растет, иногда быстро и иногда остается стабильным. Лишь редко он падает. Я утечка памяти или что-то не так в коде?
EDIT:
Я вставил этот код после вызова Пикассо в getView()
if (BuildConfig.DEBUG) {
Log.i("HEAP SIZE",
String.valueOf((Runtime.getRuntime().totalMemory() / 1024)
- (Runtime.getRuntime().freeMemory() / 1024)));
}
и я обнаружил, что рост размера кучи происходит в getView()
после загрузки растрового изображения в ImageView.
Что не так?
EDIT 2: попытался установить статический ImageAdapter, ничего не изменилось
ИЗМЕНИТЬ 3:
попробовал с RecyclerView вместо ListView, такое же поведение: размер кучи растет непрерывно, при прокрутке списка изображений с шагом 30-40 байт на каждом onBindViewHolder()
. После вращения устройства размер кучи увеличивается, иногда даже на 2-3 Мбайт. Редко он падает.
Почему размер кучи медленно, но постоянно растет и почему я пропускаю кеш или некоторые кэшированные растровые изображения после поворота устройства?
UPDATE:
попробовал адаптер без кода в конструкторе (без new OkHttpClient
и new Picasso.Builder
), он работает, и размер кучи теперь падает и остается стабильным. Затем, каков правильный способ инициализации клиента с помощью управления заголовками файлов?
развязка: наконец, я создал свой класс PicassoInstance, который создает уникальный статический синтаксис Picasso и устанавливает его как одноэлементную библиотеку Picasso. Затем я установил его в свой конструктор адаптера
PicassoInstance.setPicassoSingleton(context);
Это хорошо работает, и я надеюсь, что это правильный способ.
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();
}
}