2016-06-23 43 views
0

我正在使用我的WebServices中的Volley API,然後使用SQLITE寫入數據。android-如何緩存圖像並顯示離線?

Webservices附帶有許多itens的JSON,每個都有數據和圖像,我需要將此圖像保存在緩存中以在ListView中以及稍後在詳細信息屏幕中顯示。將來,用戶將清理這些問題並清除它們的圖像。

那麼,如何將這些圖像保存在我的本地數據庫中,並與我從JSON獲得的每個項目鏈接?

我會在90%的時間內離線。我將只保持聯機進行同步並下載更新的服務器項目。

+0

您可以使用通用圖像裝載機或畢加索;這些庫自動管理圖像緩存,並且是非常可定製的 – crgarridos

+0

我聽說過畢加索,但我不知道畢加索能否離線顯示圖像 – LMaker

+0

實際上他們都可以做到這一點。您只需加載一次圖像,圖書館爲您管理所有圖像(內部)。畢加索沒有配置和UIL在你的應用類第一次初始化 – crgarridos

回答

1

對於圖像處理的Android基準是使用Picasso庫。它需要照顧:

  • 在適配器中處理ImageView回收和下載取消;
  • 複雜的圖像轉換與最小的內存使用;
  • 自動內存和磁盤緩存。

除此之外,如果你要在列表中顯示的圖像和動畫的需要,以提高你的UI,我強烈建議從ListView控件更改爲RecyclerView。 建議不要將圖像存儲在數據庫中,否則會丟失將其從/轉換爲斑點的時間(請檢查herehere)。說,我建議是:

  1. 使用畢加索從JSON提供的URL中加載圖像;
  2. 實現自定義目標來處理畢加索下載的圖像文件;
  3. 將圖像保存在app目錄內的文件夾中;
  4. 使用RecyclerView顯示圖像; (可選)

如果你需要一個項目的例子,那麼你可以檢查this。在這個項目中,我遵循上面描述的方法。您可以從商店下載應用程序,並查看它將如何下載圖像。

Quicky導向:

  1. 要使用畢加索內容添加到您模塊的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 .load(URL) .fit() .centerCrop() .into(viewHolder.cover, new ImageWarehouse( name, viewHolder.cover, Constants.MEDIA_CHARACTER ) );

+2

謝謝你的隊友,你救了我!感謝您的驚人解釋 – LMaker

1

你可以使用Android-Universal-Image-Loader它也是在內存中緩存圖片。它顯示從緩存當下一次相同的url用於圖像加載器獲取圖像

請參閱下面的鏈接爲通用圖像加載程序示例的完整源代碼。

Android - Universal Image Loader

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