如何正确设置 Volley 从 URL 下载图像

2024-01-10

我知道 Volley 应该让下载和缓存图像变得简单,但我已经努力了几个小时才能正确实现它。我浏览过网络以及 stackoverflow 上有关 volley 的许多文章,但我发现的示例似乎都不适合我。

我只想使用 volley 从给定的 url 下载和缓存图像,而不是执行任何 HTTP JSON REST 处理。只需要获取给定的 url,下载位图并将它们设置到 imageview,然后将它们添加到缓存中。

这是迄今为止我的最新尝试。 如何正确加载和缓存volley图像?

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);
}

}


(抱歉英语水平不好^^;)

Volley 应该让下载和缓存图像变得简单

是的!截击非常简单。你不需要考虑缓存命中、图像加载等......

只需使用NetworkImageView。下面是示例。

布局示例.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. and ImageLoader 自动使用内存lru缓存和磁盘缓存。 NetworkImageView是最适合您的解决方案。

附加信息

NetworkImageView
       |
  ImageLoader (uses `LruBitmapCache` you implemented.)
       |
 RequestQueue (uses `DiskBasedCache`. it is already implemented in volley.)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何正确设置 Volley 从 URL 下载图像 的相关文章

  • 在应用程序简历中隐藏软键盘

    我有一个 Android 应用程序 使用 Xamarin 用 C 编写 我已将应用程序简化为包含 TextView 和用于横幅广告的 Google admod AdView 的 LinearLayout 我不希望软键盘出现在应用程序中 这不
  • Android 通知进度条冻结

    这是我正在使用的代码 http pastebin com 3bMCKURu http pastebin com 3bMCKURu 问题是 一段时间后 文件变得更重 通知栏下拉速度变慢 最后它就冻结了 你的通知太频繁了 这就是它冻结的原因 让
  • getItem 与 getItemAtPosition

    有两种方法可以获取列表视图中的选定项目 list getAdapter getItem position list getItemAtPosition position 我的问题是 哪一种是首选的做法 我见过人们同时使用这两种方法 您可以使
  • 使用 Android 前台服务为 MediaPlayer 创建通知

    问题就在这里 我目前正在开发一个应用程序 该应用程序必须提供 A 广播播放器 来自 URL 的 AAC 直播 还有一个播客播放器 来自 URL 的 MP3 流 该应用程序必须能够在后台运行 Android 服务 并通过以下方式向用户公开持续
  • 检测到设备正在振动?

    我使用下面的代码来振动设备 public void vibrator try Vibrator vibrator Vibrator getSystemService Context VIBRATOR SERVICE vibrator vib
  • Android - 如何一次只允许播放一个 MediaPlayer 实例?

    我正在尝试创建一个简单的 Sound board Android 应用程序 使用 ListView 项目作为按钮 顺便说一句 我是一个新手程序员 我的想法是 我按下一个按钮 就会播放一个特定的声音文件 如果我在播放声音时按下任何按钮 它应该
  • Android第一次动画不流畅

    我正在尝试一个动画将 imageView 从屏幕底部滑动到屏幕中心 但是当我第一次执行此动画时 它不平滑 但当第二次执行动画时 它是正常且平滑的 我几乎尝试了所有方法 但无法解决我的问题 这是我的动画文件
  • Android 应用程序在后台运行时保存数据

    目前我正在开发 xmmp 客户端 当应用程序位于前台时 该客户端工作得很好 但由于事实上 当应用程序处于后台时 我在 Application 类中保存了大量数据 复杂的 ArrayList 字符串和布尔值作为公共静态 每个字段都被垃圾收集
  • 与 Admob 广告单元 ID 混淆

    我跟着tutorial https developers google com admob android quick start在我的应用程序中创建广告横幅 到目前为止 这有效 我可以看到测试广告 但是 本教程指示我在两个不同的位置使用两
  • 如何将安卓手机从睡眠状态唤醒?

    如何以编程方式将 Android 手机从睡眠状态唤醒 挂起至内存 我不想获取任何唤醒锁 这意味着手机在禁用 CPU 的情况下进入 真正的 睡眠状态 我想我可以使用某种RTC 实时时钟 机制 有人有例子吗 Thanks 为了让Activity
  • (Ionic 2)尝试回退到 Cordova-lib 执行时发生错误:TypeError:无法读取未定义的属性“then”

    Edit 使用 ionic 2 时会发生这种情况 我知道它还不稳定 但我认为可能有一些解决方案 因为其他人似乎没有遇到这个问题 Edit end 由于某种原因 我在尝试使用 ionic build android 和 ionic build
  • 在意图过滤器中使用多个操作时的默认值

    尝试理解 Android 中的意图和操作并查看文档 http developer android com guide topics intents intents filters html 但我一直看到的一件事是定义了多个操作的意图过滤器
  • 获取 AlarmManager 中活动的 PendingIntents 列表

    我有办法获取活动列表PendingIntent在设备中 我开始工作AlarmManager我想看看我的PendingIntents 已正确创建和删除 也很高兴看到其他什么PendingIntent在那里 只是为了看看某些应用程序是否正在做一
  • Android 版 Robotium - solo.searchText () 不起作用

    我在使用 Robotium 时遇到 searchText 函数问题 我正在寻找这个字符串
  • Flutter 深度链接

    据Flutter官方介绍深层链接页面 https flutter dev docs development ui navigation deep linking 我们不需要任何插件或本机 Android iOS 代码来处理深层链接 但它并没
  • 如何在C(Linux)中的while循环中准确地睡眠?

    在 C 代码 Linux 操作系统 中 我需要在 while 循环内准确地休眠 比如说 10000 微秒 1000 次 我尝试过usleep nanosleep select pselect和其他一些方法 但没有成功 一旦大约 50 次 它
  • 检查 Android 手机上的方向

    如何查看Android手机是横屏还是竖屏 当前配置用于确定要检索的资源 可从资源中获取Configuration object getResources getConfiguration orientation 您可以通过查看其值来检查方向
  • 如何将设备连接到Eclipse?

    我无法解决这个简单的问题 我正在尝试通过 USB 电缆将我的设备连接到 Eclipse 在我的 PC 上 我已经安装了 Eclipse 和 Android SDK 并且在模拟器上运行该程序运行良好 我已在我的电脑上下载并安装了 Samsun
  • 将 JSON 参数从 java 发布到 sinatra 服务

    我有一个 Android 应用程序发布到我的 sinatra 服务 早些时候 我无法读取 sinatra 服务上的参数 但是 在我将内容类型设置为 x www form urlencoded 之后 我能够看到参数 但不完全是我想要的 我在
  • Android中webview的截图方法

    我在 webview 中的 html5 canvas 上画了一些线 并尝试使用下面的代码截取 webview 的屏幕截图 WebView webView WebView findViewById R id webview webView s

随机推荐