2015-08-27 3 views
0

Я использую picasso для загрузки изображений с сервера в свой список адаптеров. Когда я список прокрутки вверх и вниз Пикассо продолжает выделять все больше и больше памяти, экран ниже: enter image description herePicasso в списке адаптеров не загружает изображения из кеша

Вот часть моего списка адаптера:

@Override 
    public View getView(final int position, View convertView, ViewGroup viewGroup) { 
     ViewHolder viewHolder; 

     if (convertView == null || convertView.getTag() == null) { 
      //init list item 
      viewHolder = new ViewHolder(); 

      LayoutInflater inflater = (LayoutInflater) mContext 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.subfood_item, viewGroup, 
        false); 

      viewHolder.mImgvPicture = (ImageView) convertView.findViewById(R.id.imgvPicture); 
      viewHolder.mTvHeader = (TextView) convertView.findViewById(R.id.tvHeader); 
      viewHolder.mTvDescription = (TextView) convertView.findViewById(R.id.tvDescription); 

      convertView.setTag(viewHolder); 
     } else { 
      //list item is used again - get all references for view 
      viewHolder = (ViewHolder) convertView.getTag(); 
     } 
     Product product = mItems.get(position); 

     viewHolder.mTvHeader.setText(product.getName()); 
     viewHolder.mTvDescription.setText(product.getDescription()); 


     if (product.isAsset()) { 
      String folderPath = "file:///android_asset/product/"; 
      Picasso.with(mContext).load(folderPath + product.getPath()).fit().centerCrop(). 
        into(viewHolder.mImgvPicture); 
     } else { 
      RestUtils.loadImageWithPicasso(RestUtils.URL_IMAGE_FROM_PRODUCT + product.getNetId(), viewHolder.mImgvPicture); 
     } 


     return convertView; 
    } 

Первая часть - загрузка из активов в порядке. Проблема связана с:

RestUtils.loadImageWithPicasso(RestUtils.URL_IMAGE_FROM_PRODUCT + product.getNetId(), viewHolder.mImgvPicture); 

Я обернул это дополнительным методом из-за аутентификации сервера и автономного кэширования. Ниже приведен код RestUtils.loadImageWithPicasso

public static void loadImageWithPicasso(String url, ImageView imageView) { 
     float dp = App.getContext().getResources().getDisplayMetrics().density; 
     if(dp<=4.0f){ 
      url = url+"?size="+(int)Math.floor(dp); 
     } else { 
      url = url+"?size=4"; 
     } 

     String requestUrl = RestUtils.getUrl(url); 

     OkHttpClient picassoClient = new OkHttpClient(); 

     final String finalUrl = url; 
     String hash = RestUtils.getHashed(finalUrl); 
     Interceptor interceptor = new Interceptor() { 
      @Override 
      public Response intercept(Chain chain) throws IOException { 
       Request newRequest = chain.request().newBuilder() 
         .addHeader(RestUtils.HEADER, RestUtils.getHashed(finalUrl)) 
         .build(); 
       return chain.proceed(newRequest); 
      } 
     }; 

     picassoClient.interceptors().add(interceptor); 

     File httpCacheDir = new File(App.getContext().getExternalCacheDir(), RestUtils.IMAGE_CACHE); 
     long httpCacheSize = 40 * 1024 * 1024; 
     Cache cache = new Cache(httpCacheDir, httpCacheSize); 
     picassoClient.setCache(cache); 

     Picasso picasso = new Picasso.Builder(App.getContext()).downloader(new OkHttpDownloader(picassoClient)).build(); 

     picasso.load(requestUrl) 
       .into(imageView); 
    } 

Даже если я ушел из фрагмента, память по-прежнему выделяется.

+0

Возможно ли, что ваш сервер возвращает изображение с кодом состояния 200, а не 304 Не изменен? – axierjhtjz

+0

Вот ответ сервера https://imgur.com/RQPn34T – user1483208

+0

@axierjhtjz, поэтому он должен вернуть 304? – user1483208

ответ

2

Не уверен, что вы можете обвинить пикассо в этом. Вы создаете экземпляр Picasso с новым кешем при каждой загрузке изображения. Каждый раз, когда вы звоните loadImageWithPicasso, ваш код выделяет по меньшей мере следующие новые объекты - OkHttpClient, Interceptor, File, Cache, Picasso и не менее двух String. Один раз вы должны создавать свой экземпляр Picasso.

Существует несколько способов сделать это. Одним из них является -

Divide loadImageWithPicasso на два метода createCustomPicasso, которая возвращает пользовательский объект Picasso, вызов, который раз в коде пользовательского интерфейса и сохранить в переменной-члена.

Затем измените loadImageWithPicasso так, что он принимает экземпляр Picasso можно передать -

public static void loadImageWithPicasso(Picasso picasso, String url, ImageView imageView) 

и затем это сделать URL-адрес конкретной модификации до выдачи запросов.

Как последнее примечание, ваш Interceptor должен получать данные, необходимые для изменения запроса из chain.getRequest(), вместо использования данных из-за пределов его непосредственной сферы. Вы указываете finalUrl внутри вашего перехватчика. Он как можно заменить на chain.getRequest().urlString() См. Документацию на interceptors для хорошей прогулки по использованию.

Смежные вопросы