我知道Volley应该简单地下载和缓存图像,但我已经挣扎了几个小时才能正确实现它。我已经浏览了网络以及有关凌空的stackoverflow上的许多文章,但我发现的所有示例似乎都不适合我。
我只想使用volley来下载和缓存来自给定URL的图像,而不是进行任何HTTP JSON REST处理。只需要获取给定的URL,下载位图并将它们设置为imageview,然后将它们添加到缓存中。
这是我迄今为止的最新尝试。 如何正确加载和缓存图像?
if (data.getImageUrl() != null) {
try {
holder.thumbnail.setTag(data.getImageUrl());
Cache cache = ImgController.getInstance().getRequestQueue().getCache();
Cache.Entry entry = cache.get(data.getImageUrl());
if (entry != null) {
try {
String cImg = new String(entry.data, "UTF-8");
LruBitmapCache bitmapCache = new LruBitmapCache();
holder.thumbnail.setImageBitmap(bitmapCache.getBitmap(cImg));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else {
ImageLoader imageLoader = ImgController.getInstance().getImageLoader();
imageLoader.get(data.getImageUrl(), new ImageListener() {
@Override
public void onErrorResponse(VolleyError error) {
holder.thumbnail.setImageResource(R.drawable.filler_icon);
}
@Override
public void onResponse(ImageLoader.ImageContainer response, boolean arg1) {
if (response.getBitmap() != null) {
// load image into imageview
holder.thumbnail.setImageBitmap(response.getBitmap());
}
}
});
}
return convertView;
} catch (Exception e) {
e.printStackTrace();
Log.v(DEBUG_TAG, "no image: ", e);
holder.thumbnail.setImageResource(R.drawable.filler_icon);
}
}else {
return null;
}
return convertView;
}
当我运行它时,我得到一个指向此行的NullPointerException
Cache cache = ImgController.getInstance().getRequestQueue().getCache();
我已设置以下单例类来处理请求
public class ImgController extends Application {
public static final String TAG = ImgController.class.getSimpleName();
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private static ImgController instance;
@Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static synchronized ImgController getInstance(){
return instance;
}
public RequestQueue getRequestQueue(){
if(requestQueue == null){
requestQueue = Volley.newRequestQueue(getApplicationContext());
}
return this.requestQueue;
}
public ImageLoader getImageLoader(){
getRequestQueue();
if(imageLoader == null){
imageLoader = new ImageLoader(this.requestQueue, new LruBitmapCache());
}
return this.imageLoader;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (requestQueue != null) {
requestQueue.cancelAll(tag);
}
}
}
以及以下LruBitmapCache类
public class LruBitmapCache extends LruCache<String, Bitmap> implements ImageLoader.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 maxSize) {
super(maxSize);
}
@Override
public Bitmap getBitmap(String url) {
return get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put (url, bitmap);
}
}
答案 0 :(得分:8)
(抱歉英语能力差^^;)
Volley应该让人无意识地下载和缓存图像
是啊!排球非常简单。你不需要考虑缓存命中,图像加载等......
只需使用NetworkImageView
即可。贝鲁斯就是榜样。
layout_example.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/photo"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_example);
NetworkImageView nv = (NetworkImageView) findViewById(R.id.photo);
nv.setDefaultImageResId(R.drawable.default_image); // image for loading...
nv.setImageUrl(imageUrl, ImgController.getInstance().getImageLoader()); //ImgController from your code.
}
NetworkImageView
会自动从后台队列加载图像,并在分离此视图时取消请求using ImageLoader
。并且ImageLoader
会自动使用内存直通缓存和磁盘缓存。 NetworkImageView
是最适合您的解决方案。
NetworkImageView
|
ImageLoader (uses `LruBitmapCache` you implemented.)
|
RequestQueue (uses `DiskBasedCache`. it is already implemented in volley.)
答案 1 :(得分:7)
Volley可以使用图像请求的回调,您可以使用下面的代码。
ImageView iv = null; /*Attach the Pointer for ImageView*/
RequestQueue requestAdministrator = null; /*Attach the Pointer for Volley*/
ImageRequest ir = new ImageRequest(url, new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
// callback
iv.setImageBitmap(response);
}
}, 100, 100, null, null);
// 100 is your custom Size before Downloading the Image.
requestAdministrator.add(ir);
答案 2 :(得分:1)
ImageRequest 已弃用,因此我按以下方式执行此操作:
第1步:首先制作应用课程
public class YourApplicationClass extends Application {
private static YourApplicationClass sInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
public static YourApplicationClass getInstance(){
return sInstance;
}
@Override
public void onCreate() {
super.onCreate();
sInstance = this;
mRequestQueue = Volley.newRequestQueue(this);
mImageLoader = new ImageLoader(this.mRequestQueue, new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap> mCache = new LruCache<String, Bitmap>(10);
public Bitmap getBitmap(String url) {
return mCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
mCache.put(url, bitmap);
}
});
}
public RequestQueue getRequestQueue(){
return mRequestQueue;
}
public ImageLoader getImageLoader(){
return mImageLoader;
}
}
第2步:现在,从任何活动或片段
按照以下方式发出图像请求YourApplicationClass.getInstance().getImageLoader().get(image_url, new ImageLoader.ImageListener() {
@Override
public void onResponse(ImageLoader.ImageContainer imageContainer, boolean b) {
Bitmap bitmap = imageContainer.getBitmap();
//use bitmap
}
@Override
public void onErrorResponse(VolleyError volleyError) {
}
});
答案 3 :(得分:0)
答案 4 :(得分:0)
我有一个更简单的解决方案,用于显示来自url的图像并将其存储在缓存中。无需添加其他类,只需添加MainActivity。 可能它会帮助某人...
这是我的XML,只显示ImageView
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.natalie.volley.MainActivity">
<ImageView
android:id="@+id/ivImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="50dp"/>
</android.support.constraint.ConstraintLayout>
这是我的MainAvtivity.java:
import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageRequest;
import com.android.volley.toolbox.Volley;
public class MainActivity extends AppCompatActivity {
private String url = "http://kingofwallpapers.com/picture/picture-010.jpg";
ImageView ivImageView;
RequestQueue mRequestQueue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivImageView = (ImageView)findViewById(R.id.ivImageView);
mRequestQueue = Volley.newRequestQueue(this.getApplicationContext());
ImageRequest imageRequest = new ImageRequest(url, new BitmapListener(), 0, 0, null, null, new MyErrorListener());
mRequestQueue.add(imageRequest);
}
private class BitmapListener implements Response.Listener<Bitmap> {
@Override
public void onResponse(Bitmap response) {
// response = your url's bitmap
ivImageView.setImageBitmap(response);
}
}
private class MyErrorListener implements Response.ErrorListener {
@Override
public void onErrorResponse(VolleyError error) {
//store a default image if connection failed
ivImageView.setImageResource(R.drawable.error_icon);
}
}
}
不要忘记在Manifest.xml中添加<uses-permission android:name="android.permission.INTERNET" />
和build.gradle依赖项中的compile 'com.android.volley:volley:1.0.0'