2013-07-15 40 views
10

Tôi đang sử dụng lớp imageLoader để tải hình ảnh từ url. Nhưng tất cả những hình ảnh đó đều được lưu trữ trong thư viện bằng tên thư mục có tên LazyList. Nó chiếm tới 40 -100 mb bộ nhớ. Nhưng tôi không muốn tải hình ảnh đó vì người dùng có thể cảm thấy khó chịu. Xin lỗi vì tiếng Anh xấu.Lớp Trình tải hình ảnh tạo thư mục lazylist trong thư viện. Cách tránh nó

Tất cả đều hoạt động tốt nhưng nó tạo một thư mục trong thư viện và hiển thị tất cả hình ảnh đang được ứng dụng của tôi sử dụng. Vì vậy, tôi cảm thấy người dùng sẽ cảm thấy khó chịu bởi ứng dụng của tôi.

Đây là mã của tôi về imageloader và cũng nó liên kết với vài lớp khác thậm chí

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

Khi lưu trữ hình ảnh trong thẻ SD, hãy thêm tệp '.nomedia' vào thư mục. Xem, ví dụ, http://stackoverflow.com/a/17800556 – ozbek

+0

@shoerat Có nó hoạt động ... nhưng vấn đề là nếu tôi muốn hiển thị hình ảnh cụ thể cho người dùng được lưu tôi không thể làm điều đó từ bây giờ. Trước đây tôi liên kết trực tiếp thay vì gọi url –

Trả lời

5

tôi có giải pháp của tôi bằng cách thay đổi FileCache của tôi lớp và thư mục đích của nó

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

Bạn có thể sử dụng thư viện droidQuery hình ảnh tải lười biếng từ URL, sau đó bộ nhớ cache chúng trên một cơ sở cho mỗi phiên làm việc. Bạn cũng có thể xử lý bộ đệm ẩn của riêng mình, chẳng hạn như SharedPreferences hoặc cơ sở dữ liệu SQLite. Để tải về những hình ảnh, sử dụng phương pháp dài tay:

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

để lưu dữ liệu vào một cơ sở dữ liệu hoặc SharedPreferences, đọc qua các tài liệu: http://developer.android.com/guide/topics/data/data-storage.html

+0

Tôi đã có thể hiển thị và lưu trữ hình ảnh nhưng vấn đề là: chúng đang hiển thị trong thư viện của tôi. Mỗi hình ảnh trong ứng dụng của tôi có thể được nhìn thấy trong thư viện và tôi không muốn nó được thực hiện –

Các vấn đề liên quan