2013-07-15 51 views
10

我正在使用imageLoader類從URL加載圖像。但是這些所有圖像都通過名爲LazyList的文件夾名稱存儲在圖庫中。它需要高達40 -100 MB的內存。但我不想加載該圖像,因爲用戶可能會感到不適。對不起英文不好。Imageloader類在庫中創建lazylist文件夾。如何避免它

所有工作正常,但它會在圖庫中創建一個文件夾,並顯示我的應用程序正在使用的所有圖像。所以我覺得用戶會因爲我的應用感到不舒服。

這裏是我的ImageLoader的代碼並且還與其他幾個班級甚至

public class ImageLoader { 
MemoryCache memoryCache = new MemoryCache(); 
FileCache fileCache; 
private Map<ImageView, String> imageViews = Collections 
     .synchronizedMap(new WeakHashMap<ImageView, String>()); 
ExecutorService executorService; 

public ImageLoader(Context context) { 
    fileCache = new FileCache(context); 
    executorService = Executors.newFixedThreadPool(5); 
} 

final int stub_id = R.drawable.abs__ab_bottom_transparent_light_holo; 

public void DisplayImage(String url, ImageView imageView) { 
    imageViews.put(imageView, url); 
    Bitmap bitmap = memoryCache.get(url); 
    if (bitmap != null) 
     imageView.setImageBitmap(bitmap); 
    else { 
     queuePhoto(url, imageView); 
     imageView.setImageResource(stub_id); 
    } 
} 

private void queuePhoto(String url, ImageView imageView) { 
    PhotoToLoad p = new PhotoToLoad(url, imageView); 
    executorService.submit(new PhotosLoader(p)); 
} 

private Bitmap getBitmap(String url) { 
    File f = fileCache.getFile(url); 
    // from SD cache 
    Bitmap b = decodeFile(f); 
    if (b != null) 
     return b; 
    // from web 
    try { 
     Bitmap bitmap = null; 
     URL imageUrl = new URL(url); 
     HttpURLConnection conn = (HttpURLConnection) imageUrl 
       .openConnection(); 
     conn.setConnectTimeout(30000); 
     conn.setReadTimeout(30000); 
     conn.setInstanceFollowRedirects(true); 
     InputStream is = conn.getInputStream(); 
     OutputStream os = new FileOutputStream(f); 
     Utils.CopyStream(is, os); 
     os.close(); 
     bitmap = decodeFile(f); 
     return bitmap; 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
     return null; 
    } 
} 

// decodes image and scales it to reduce memory consumption 
private Bitmap decodeFile(File f) { 
    try { 
     // decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeStream(new FileInputStream(f), null, o); 
     // Find the correct scale value. It should be the power of 2. 
     final int REQUIRED_SIZE = 100; 
     int width_tmp = o.outWidth, height_tmp = o.outHeight; 
     int scale = 1; 
     while (true) { 
      if (width_tmp/2 < REQUIRED_SIZE 
        || height_tmp/2 < REQUIRED_SIZE) 
       break; 
      width_tmp /= 2; 
      height_tmp /= 2; 
      scale *= 2; 
     } 
     // decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
    } catch (FileNotFoundException e) { 
    } 
    return null; 
} 

// Task for the queue 
private class PhotoToLoad { 
    public String url; 
    public ImageView imageView; 

    public PhotoToLoad(String u, ImageView i) { 
     url = u; 
     imageView = i; 
    } 
} 

class PhotosLoader implements Runnable { 
    PhotoToLoad photoToLoad; 

    PhotosLoader(PhotoToLoad photoToLoad) { 
     this.photoToLoad = photoToLoad; 
    } 

    @Override 
    public void run() { 
     if (imageViewReused(photoToLoad)) 
      return; 
     Bitmap bmp = getBitmap(photoToLoad.url); 
     memoryCache.put(photoToLoad.url, bmp); 
     if (imageViewReused(photoToLoad)) 
      return; 
     BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad); 
     Activity a = (Activity) photoToLoad.imageView.getContext(); 
     a.runOnUiThread(bd); 
    } 
} 

boolean imageViewReused(PhotoToLoad photoToLoad) { 
    String tag = imageViews.get(photoToLoad.imageView); 
    if (tag == null || !tag.equals(photoToLoad.url)) 
     return true; 
    return false; 
} 

// Used to display bitmap in the UI thread 
class BitmapDisplayer implements Runnable { 
    Bitmap bitmap; 
    PhotoToLoad photoToLoad; 

    public BitmapDisplayer(Bitmap b, PhotoToLoad p) { 
     bitmap = b; 
     photoToLoad = p; 
    } 

    public void run() { 
     if (imageViewReused(photoToLoad)) 
      return; 
     if (bitmap != null) 
      photoToLoad.imageView.setImageBitmap(bitmap); 
     else 
      photoToLoad.imageView.setImageResource(stub_id); 
    } 
} 

public void clearCache() { 
    memoryCache.clear(); 
    fileCache.clear(); 
} 
} 
+1

將圖像存儲在SD卡中時,將'.nomedia'文件添加到文件夾中。例如,請參閱http://stackoverflow.com/a/17800556 – ozbek

+0

@shoerat是的,它的工作原理......但問題是如果我想爲保存的用戶顯示特定的映像,我無法從現在開始。以前我直接鏈接它而不是調用url –

回答

5

我改變我的FileCache了我的解決辦法類和目標文件夾

public class FileCache { 
    private File cacheDir; 
    private File nomediaFile; 
    String NOMEDIA = " .nomedia"; 
public FileCache(Context context) { 
    // Find the dir to save cached images 
    if (android.os.Environment.getExternalStorageState().equals(
      android.os.Environment.MEDIA_MOUNTED)) { 
     cacheDir = new File(Environment.getExternalStorageDirectory() 
       + "/mydir"); 
     if (cacheDir.mkdir()) { 
      nomediaFile = new File(
        Environment.getExternalStorageDirectory() + "/mydir/" 
          + NOMEDIA); 
      if (!nomediaFile.exists()) { 
       try { 
        nomediaFile.createNewFile(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } else { 
     cacheDir = context.getCacheDir(); 
    } 
    if (!cacheDir.exists()) 
     cacheDir.mkdirs(); 
} 

public File getFile(String url) { 
    // I identify images by hashcode. Not a perfect solution, good for the 
    // demo. 
    // String filename=String.valueOf(url.hashCode()); 
    // Another possible solution (thanks to grantland) 
    @SuppressWarnings("deprecation") 
    String filename = URLEncoder.encode(url); 
    File f = new File(cacheDir, filename); 
    return f; 

} 

public void clear() { 
    File[] files = cacheDir.listFiles(); 
    if (files == null) 
     return; 
    for (File f : files) 
     f.delete(); 
} 
} 
1

可以使用droidQuery庫延遲加載圖片來自網址,然後緩存他們在每個會話鏈接。您也可以處理自己的緩存,例如到SharedPreferences或SQLite數據庫。要下載圖像,使用長手方法:

$.ajax(new AjaxOptions().url("http://www.example.com") 
         .type("GET") 
         .dataType("image") 
         .timeout(30000) 
         .cache(true) 
         .cacheTimeout(600000)//milliseconds 
         //consider using .imageWidth() or .imageHeight() methods to control output size 
         .success(new Function() { 
          @Override 
          public void invoke($ droidQuery, Object... params) { 
           myImageView.setImageBitmap((Bitmap) params[0]); 
           //save raw bitmap across sessions, maybe. 
          } 
         }); 

將數據保存到一個數據庫SharedPreferences,通讀文件:http://developer.android.com/guide/topics/data/data-storage.html

+0

我能夠顯示和存儲圖像,但問題是:它們顯示在我的畫廊中。我的應用程序中的每個圖像都可以在圖庫中看到,我不希望這樣做 –