android - 如何缓存图像和脱机显示?

时间:2016-06-23 14:18:07

标签: android json sqlite caching

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

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

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

我将在90%的时间内离线。我将只保持联机以同步和下载更新的服务器项目。

3 个答案:

答案 0 :(得分:1)

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

请参阅以下链接,了解Universal Image Loader示例的完整源代码。

Android - Universal Image Loader

答案 1 :(得分:1)

为了处理Android中的图像,基准测试是使用Picasso库。它负责:

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

除此之外,如果您要在列表中显示图像并需要动画来增强UI,我强烈建议您从ListView更改为RecyclerView。 建议不要将图像存储在数据库中,否则会浪费时间从/向Blob转换(检查herehere)。说,我的建议是:

  1. 使用Picasso从JSON中提供的URL加载图像;
  2. 实施自定义目标以处理Picasso下载的图像文件;
  3. 将图像保存在应用目录内的文件夹中;
  4. 使用RecyclerView显示图像; (可选)
  5. 如果您需要一个完成这些工作的项目示例,您可以查看this。在这个项目中,我遵循上面描述的方法。您可以从商店下载该应用程序,并查看它将如何下载图像。

    Quicky导:

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

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

      public class ImageWarehouse实现Callback {     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 :(得分:0)

您可以将图像保存为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);
}