2015-11-17 3 views
0

Кто-нибудь мог решить проблему кеширования при загрузке изображений с AWS S3?Проблемы с кешем Пикассо с AMAZON S3

Я использую OKHttpClient и все, что Jazz, но он выглядит как cacheControl или что-то еще не проверяет изменения в заголовках ETag и LAST_MODIFIED. Он всегда берет кешированную версию.

Я инициализации Пикассо так:

OkHttpClient client = new OkHttpClient(); 
Picasso.Builder builder = new Picasso.Builder(appContext).downloader(new OkHttpDownloader(client)); 
Picasso built = builder.build(); 
Picasso.setSingletonInstance(built); 

И заголовки ответа выглядеть так:

D/OkHttpDownloader: x-amz-id-2: gWhBHQvzDw1RFDteg8uxvq02XfaB6SySgMgKMk45x2E6An245Bl0OjgYgKsHMxzkVm2nF4GPwRI=<br/> 
D/OkHttpDownloader: x-amz-request-id: D80E5602FF3E6002 
D/OkHttpDownloader: Date: Tue, 17 Nov 2015 14:46:02 GMT 
D/OkHttpDownloader: Last-Modified: Sun, 01 Nov 2015 15:39:41 GMT 
D/OkHttpDownloader: ETag: "2a082d4f2d42de95cc1b673a7742fec3" 
D/OkHttpDownloader: Accept-Ranges: bytes 
D/OkHttpDownloader: Content-Type: image/png 
D/OkHttpDownloader: Content-Length: 798624 
D/OkHttpDownloader: Server: AmazonS3 
D/OkHttpDownloader: OkHttp-Selected-Protocol: http/1.1 
D/OkHttpDownloader: OkHttp-Sent-Millis: 1447771561871 
D/OkHttpDownloader: OkHttp-Received-Millis: 1447771562179 

Edit:

Ok. После добавления заголовка управления кэшем в запрос объекта put («must-revalidate» было моим оружием выбора), он частично решил проблему.

Для того, чтобы заставить запущенное приложение, чтобы обновить заменяемый образ, который я должен был сопровождать, что со следующим:

// Remove from memory cache 
Picasso.with(appContext).invalidate(imageUrl); 
// Remove from disc cache 
Iterator<String> it = okHttpClient.getCache().urls(); 
while(it.hasNext()){ 
    String currentUrl = it.next(); 

    if(currentUrl.equals(imageUrl)){ 
    it.remove();       
    break; 
    } 
} 
// Update cache with new image 
Picasso.with(appContext).load(imageUrl).fetch(); 

ответ

0

Expires: или Cache-Control: заголовки, в частности, отсутствуют в вашем ответе, что говорит о том, что при загрузке файлов на S3 вы их не устанавливали - так что вы по прихоти зрителя для поведения кэширования.

Установка Cache-Control: max-age=3600 (или любой другой срок службы, который вы хотите) при загрузке на S3 приведет к возврату этих заголовков вместе с объектом при его загрузке. Или вы можете вернуться на консоль S3 и установить их после загрузки объекта. Вы также можете программно добавить их к уже загруженным объектам, отправив вызов API на S3 для копирования объекта на себя с измененными метаданными.

0

После нескольких часов (возможно, дней), пытаясь выяснить, как кэшировать изображения в Пикассо, и, не желая раскручивать собственное решение, я просто переключил библиотеки на Fresco Facebook. Они используют очень интересную стратегию, когда вы заменяете ImageViews на SimpleDraweeViews. Все, что вам нужно сделать, это установить URI в DraweeView, и Fresco загрузит изображение в представление, как только оно будет готово. Он также автоматически кэширует изображение для вас. Я очень рекомендую попробовать его.

Вот Quickstart руководство: http://frescolib.org/docs/index.html#_

Я вставить свой код ниже, который получает все работает:

build.gradle:

dependencies { 
    // your app's other dependencies 
    compile 'com.facebook.fresco:fresco:0.7.0+' 
} 

Layout XML:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="match_parent" 
      android:layout_height="200dp" 
      xmlns:fresco="http://schemas.android.com/apk/res-auto" 
      android:orientation="vertical" 
      android:layout_margin="@dimen/margin_channel_item"> 

<com.facebook.drawee.view.SimpleDraweeView 
    android:id="@+id/iv_channel_image" 
    android:scaleType="centerCrop" 
    fresco:placeholderImage="@drawable/tct_banner" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

</RelativeLayout> 

Код Java:

@Override 
public void onBindViewHolder(ViewHolder holder, final int position) { 

    // Get the current Channel 
    final TctOnDemandChannel currentChannel = mODChannels.get(position); 

    holder.channelImageView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      ((TctCoreApplication)mContext.getApplicationContext()).trackChannelClick(currentChannel); 

      ActivityEpisodesView.startWithChannelExtra(currentChannel, mContext); 
     } 
    }); 

    // TODO: Handle errors by grabbing image from Internet 
    Uri uri = Uri.parse(currentChannel.getImageUrl()); 
    holder.channelImageView.setImageURI(uri); 
} 

public class ViewHolder extends RecyclerView.ViewHolder { 

    SimpleDraweeView channelImageView; 

    public ViewHolder(View itemView) { 
     super(itemView); 
     channelImageView = (SimpleDraweeView) itemView.findViewById(R.id.iv_channel_image); 
    } 
} 

При быстрой прокрутке перед загрузкой изображений изначально короткое время, когда вы все еще можете увидеть изображение заполнителя. Но как только все загружается изначально, прокрутка безупречна (YMMV), и изображения кэшируются точно так же, как я ожидаю, что они будут без меня, чтобы что-то настроить.

Дайте мне знать, как это работает для вас.