Android Volley не кеширует изображения
Я использовал этот урок, чтобы показать и кэшировать изображение в сетке, используя Volley. когда интернет подключен, он работает нормально. но после отключения изображения не показывать. Кажется, залп не кэширует никакое изображение. проблема в том, что нет полной документации о кэшировании изображений с помощью Volley. Вот мой код:
XML:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/container_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F4F4F6"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".Content_Gallery_Activity">
<TextView
android:id="@+id/text_gallery_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:gravity="center"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:textAppearance="?android:attr/textAppearanceSmall" />
<RelativeLayout
android:id="@+id/relative_gallery"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_below="@+id/text_gallery_title"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="10dp"
android:background="@drawable/rect_lst_tree"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<com.beardedhen.androidbootstrap.AwesomeTextView
android:id="@+id/font_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/tv_date_gallery"
app:bootstrapBrand="info"
app:fontAwesomeIcon="fa_clock_o"
>
</com.beardedhen.androidbootstrap.AwesomeTextView>
<TextView
android:id="@+id/tv_date_gallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#1B131B"
android:textSize="13dp" >
</TextView>
<TextView
android:id="@+id/text_image_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/gallery_thumb"
android:text="Small"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#F01435"
android:textSize="12dp" />
<ir.whc.news.views.CircularNetworkImageView
android:id="@+id/gallery_thumb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
>
</ir.whc.news.views.CircularNetworkImageView>
</RelativeLayout>
<GridView
android:id="@+id/gridView1"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="@+id/relative_gallery"
android:columnWidth="100dp"
android:horizontalSpacing="1dp"
android:numColumns="auto_fit"
android:paddingTop="10dp"
android:stretchMode="spacingWidthUniform"
android:verticalSpacing="8dp" >
</GridView>
</RelativeLayout>
</LinearLayout>
<fragment
android:id="@+id/fragment_navigation_drawer"
android:name="ir.whc.news.activity.FragmentDrawer"
android:layout_width="@dimen/nav_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="@layout/fragment_navigation_drawer"
tools:layout="@layout/fragment_navigation_drawer" />
Actitvity:
grd.setAdapter(new MyImageAdapter(galleryItem.get_images()));
grd.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(ContentGalleryActivity.this, DisplayImageActivity.class);
intent.putExtra("largimage_url", galleryItem.get_images().get(position).get_largimage_path());
startActivity(intent);
}
});
адаптер:
class MyImageAdapter extends BaseAdapter {
ArrayList<ImageItem> imageItems;
public MyImageAdapter(ArrayList<ImageItem> imageItems)
{
this.imageItems=imageItems;
}
@Override
public int getCount() {
return imageItems.size();
}
@Override
public Object getItem(int position) {
return imageItems.get(position);
}
@Override
public long getItemId(int position) {
return imageItems.get(position).get_id();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder gridViewImageHolder;
// check to see if we have a view
if (view == null) {
view = getLayoutInflater().inflate(R.layout.grid_image_item, parent, false);
gridViewImageHolder = new ViewHolder();
gridViewImageHolder.imageView = (ImageView) view.findViewById(R.id.image_grid_networkImageView);
view.setTag(gridViewImageHolder);
} else {
gridViewImageHolder = (ViewHolder) view.getTag();
}
mNetworkImageView = (NetworkImageView) gridViewImageHolder.imageView;
mNetworkImageView.setDefaultImageResId(R.drawable.ic_launcher);
mNetworkImageView.setErrorImageResId(android.R.drawable.ic_dialog_alert);
mNetworkImageView.setAdjustViewBounds(true);
mNetworkImageView.setImageUrl(imageItems.get(position).get_thumb_path(), imageLoader);
return view;
}
}
Imageloder:
imageLoader = MyApplication.getInstance().getImageLoader();
imageLoader.get(galleryItem.get_imgPath(), imageLoader.getImageListener(img_thumb,
R.drawable.ic_launcher,
android.R.drawable.ic_dialog_alert));
img_thumb.setImageUrl(galleryItem.get_imgPath(), imageLoader);
LruBitmapCache:
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import com.android.volley.toolbox.ImageLoader.ImageCache;
public class LruBitmapCache extends LruCache<String, Bitmap> implements
ImageCache {
public static int getDefaultLruCacheSize() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
return cacheSize;
}
public LruBitmapCache() {
this(getDefaultLruCacheSize());
}
public LruBitmapCache(int sizeInKiloBytes) {
super(sizeInKiloBytes);
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
@Override
public Bitmap getBitmap(String url) {
return get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
что не так с моим кодом. Я устал от борьбы.
1 ответ
Похоже, проблема в том, что у ваших изображений нет заголовков кеша, что заставляет Volley его кешировать. Вы можете явно форсировать кеш, расширяя свой ImageLoader, который вы инициализируете в MyApplication.
например:
mImageLoader = new ImageLoader(this.mRequestQueue,
new LruBitmapCache()) {
@Override
protected Request<Bitmap> makeImageRequest(String requestUrl, int maxWidth, int maxHeight,
ScaleType scaleType, final String cacheKey) {
return new ImageRequest(requestUrl, new Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
onGetImageSuccess(cacheKey, response);
}
}, maxWidth, maxHeight, scaleType, Config.RGB_565, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onGetImageError(cacheKey, error);
}
}){
@Override
public Response<Bitmap> parseNetworkResponse(NetworkResponse response) {
Response<Bitmap> resp = super.parseNetworkResponse(response);
if(!resp.isSuccess()) {
return resp;
}
long now = System.currentTimeMillis();
Cache.Entry entry = resp.cacheEntry;
if(entry == null) {
entry = new Cache.Entry();
entry.data = response.data;
entry.softTtl = now + 1 * 60 * 60 * 1000; // keeps valid(no refresh) for 1hr
entry.responseHeaders = response.headers;
}
entry.ttl = now + 30l * 24 * 60 * 60 * 1000; //keeps cache for 30 days
return Response.success(resp.result, entry);
}
};
}
};
Таким образом, ваши изображения будут кэшироваться на диске в течение 30 дней, а также обновляться при необходимости.
подобная проблема здесь
Вот как выглядит ответ Джоджо в Котлине.
val imageLoader: ImageLoader
get() {
requestQueue
if (mImageLoader == null) {
mImageLoader = object : ImageLoader(
this.mRequestQueue,
LruBitmapCache()
) {
override fun makeImageRequest(
requestUrl: String?, maxWidth: Int,
maxHeight: Int, scaleType: ImageView.ScaleType?, cacheKey: String?
): Request<Bitmap> {
return object : ImageRequest(requestUrl,
Response.Listener<Bitmap>
{ response -> onGetImageSuccess(cacheKey, response) },
maxWidth,
maxHeight,
scaleType,
Bitmap.Config.RGB_565,
Response.ErrorListener {
onGetImageError(cacheKey, it)
}
) {
override fun parseNetworkResponse(response: NetworkResponse?): Response<Bitmap> {
val resp = super.parseNetworkResponse(response)
if (!resp.isSuccess()) {
return resp;
}
val now = System.currentTimeMillis();
var entry = resp.cacheEntry;
if (entry == null) {
entry = Cache.Entry();
entry.data = response?.data;
entry.softTtl =
now + 1 * 60 * 60 * 1000; // keeps valid(no refresh) for 1hr
entry.responseHeaders = response?.headers;
}
entry.ttl =
now + 30L * 24 * 60 * 60 * 1000; //keeps cache for 30 days
return Response.success(resp.result, entry);
}
}
}
}
}
return this.mImageLoader!!
}
Вот класс LruBitmapCache в Котлине
import android.graphics.Bitmap
import android.util.LruCache
import com.android.volley.toolbox.ImageLoader
class LruBitmapCache @JvmOverloads constructor(sizeInKiloBytes: Int
defaultLruCacheSize):LruCache<String?, Bitmap>(sizeInKiloBytes),
ImageLoader.ImageCache {
override fun sizeOf(key: String?, value: Bitmap): Int {
return value.rowBytes * value.height / 1024
}
override fun getBitmap(url: String): Bitmap {
return get(url)
}
override fun putBitmap(url: String, bitmap: Bitmap) {
put(url, bitmap)
}
companion object {
val defaultLruCacheSize: Int
get() {
val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
return maxMemory / 8
}
}
}
Надеюсь, это может кому-то помочь