【问题标题】:android - How do I caching image and display offline?android - 如何缓存图像并离线显示?
【发布时间】:2016-10-25 22:41:52
【问题描述】:

我在我的 WebServices 中使用 Volley API,然后我将使用 SQLITE 写入数据。

带有许多元素的 JSON 附带的 Web 服务,每个元素都有数据和图像,我需要将此图像保存在我的缓存中,以便在 ListView 中脱机显示,然后在详细信息屏幕上显示。未来用户将清理这些物品并清除它们的图像。

那么,如何将这些图像保存在我的本地数据库中并链接到我从 JSON 中获得的每个项目?

在 90% 的时间里,我将处于离线状态。我只会在线同步和下载更新的服务器项目。

【问题讨论】:

  • 您可以使用通用图像加载器或毕加索;这些库自动管理图像缓存并且非常可定制
  • 听说过毕加索,但不知道毕加索能不能离线显示图片
  • 其实两个都可以。您加载一次图像,图书馆为您管理所有(内部)。 Picasso 没有配置,UIL 在你的应用程序类中进行了第一次初始化

标签: android json sqlite caching


【解决方案1】:

在 Android 中处理图像的基准是使用 Picasso 库。它负责:

  • 在适配器中处理 ImageView 回收和下载取消;
  • 使用最少内存的复杂图像转换;
  • 自动内存和磁盘缓存。

除此之外,如果您要在列表中显示图像并且需要动画来增强您的 UI,我强烈建议您从 ListView 更改为 RecyclerView。 不建议将图像存储在 DB 中,您会浪费时间将其从 blob 转换为 blob (检查 herehere)。说了这么多,我的建议是:

  1. 使用 Picasso 从 JSON 中提供的 URL 加载图像;
  2. 实现一个自定义目标来处理毕加索下载的图像文件;
  3. 将图像保存在应用目录内的文件夹中;
  4. 使用 RecyclerView 显示图像; (可选)

如果您需要完成这些事情的项目示例,您可以查看this。在这个项目中,我遵循我上面描述的方法。您可以从商店下载该应用程序并查看它如何下载图像。

快速指南:

  1. 要使用 Picasso,请将其添加到模块的 gradle 文件中:compile 'com.squareup.picasso:picasso:2.5.2'

  2. 创建一个实现import com.squareup.picasso.Callback;的类:

    公共类 ImageWarehouse 实现回调 { private static final String TAG = "ImageWarehouse";

    private String mDirectory;
    private String mFileName;
    private ImageView mContainer;
    @Inject
    App mApplication;
    
    public ImageWarehouse(String fileName, ImageView container, String directory) {
        this.mFileName = fileName;
        this.mContainer = container;
        this.mDirectory = directory;
        this.getStorageDir();
    }
    
    @Override
    public void onSuccess() {
        if (this.isExternalStorageWritable()) {
            final Bitmap bitmap = ((BitmapDrawable) this.mContainer.getDrawable()).getBitmap();
            new AsyncTask<Void, Void, File>() {
                @Override
                protected File doInBackground(Void... params) {
                    File file = null;
                    try {
                        file = new File(ImageWarehouse.this.getStorageDir().getPath().concat("/").concat(ImageWarehouse.this.mFileName.concat(Constants.MEDIA_EXTENSION)));
                        file.createNewFile();
                        FileOutputStream ostream = new FileOutputStream(file);
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
                        ostream.close();
                    } catch (Exception e) {
                        Log.e(TAG, "External Storage is not available");
                    }
                    return file;
                }
            }.execute();
        } else {
            Log.e(TAG, "External Storage is not available");
        }
    }
    
    @Override
    public void onError() {
    
    }
    
    public boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            return true;
        }
        return false;
    }
    
    public File getStorageDir() {
        File file = new File(Environment.getExternalStorageDirectory(), Constants.MEDIA_DIRECTORY.concat(this.mDirectory));
        if (!file.mkdirs()) {
        }
        return file;
    }
    

    }

  3. 调用 Picasso 以便在布局中显示图像并将其保存到指定路径:

    Picasso .load(URL) .fit() .centerCrop() .into(viewHolder.cover, new ImageWarehouse( name, viewHolder.cover, Constants.MEDIA_CHARACTER ) );

【讨论】:

  • 谢谢你,伙计,你救了我!感谢您的精彩解释
【解决方案2】:

您可以使用 Android-Universal-Image-Loader 它也是内存中的缓存图像。下次在 imageloader 中使用相同的 url 获取图像时,它会从缓存中显示

Universal Image Loader Example 的完整源代码见下方链接。

Android - Universal Image Loader

【讨论】:

    【解决方案3】:

    您可以将 Sqlite 中的图像保存为 blob,并在需要时检索它。创建表为

    create table sometable(id integer primary key autoincrement,photo BLOB);
    

    并将图像另存为

    //convert image into byte[]
    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
    Bitmap bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.common)).getBitmap();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);   
    byte[] photo = baos.toByteArray();
    
    //And now store this image
    ContentValues initialValues = new ContentValues();   
    initialValues.put("photo",photo);
    return db.insert("sometable", null, initialValues);
    

    并将图像检索为

    Cursor cur=your query;
    while(cur.moveToNext())
    {
       byte[] photo=cur.getBlob(index of blob cloumn);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-20
      • 2013-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-15
      • 1970-01-01
      相关资源
      最近更新 更多