2013-07-15 26 views
10

Sto usando la classe imageLoader per caricare le immagini dall'URL. Ma quelle tutte le immagini sono memorizzate nella galleria da un nome di cartella chiamato LazyList. Richiede fino a 40 -100 mb di memoria. Ma non voglio caricare quelle immagini dal momento che gli utenti potrebbero sentirsi a disagio. Scusa per il pessimo inglese.La classe Imageloader crea una cartella lazylist nella galleria. Come evitarlo

Tutto funziona bene ma crea una cartella nella galleria e mostra tutte le immagini che utilizzano dalla mia app. Quindi sento che gli utenti si sentiranno a disagio dalla mia app.

Ecco il mio codice di ImageLoader ed inoltre collegamenti con poche altre classi anche

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

Quando si memorizzano le immagini nella scheda SD, aggiungere il file '.nomedia' alla cartella. Vedi, ad esempio, http://stackoverflow.com/a/17800556 – ozbek

+0

@shoerat Sì, funziona ... ma il problema è che se voglio mostrare un'immagine particolare per l'utente che viene salvato non posso farlo da ora. Precedentemente collego direttamente invece di chiamare l'url –

risposta

5

ho ottenuto la mia soluzione cambiando il mio FileCache classe e sua cartella di destinazione

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

È possibile utilizzare la libreria droidQuery per caricare le immagini da URL pigri, poi li cache una base per-sessione. Puoi anche gestire il tuo cacheing, come ad esempio SharedPreferences o un database SQLite. Per scaricare le immagini, utilizzare il metodo di lunga mano:

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

Per salvare i dati in un database o SharedPreferences, rileggere la documentazione: http://developer.android.com/guide/topics/data/data-storage.html

+0

Sono stato in grado di visualizzare e archiviare le immagini ma il problema è: stanno mostrando nella mia galleria. Ogni immagine nella mia app può essere vista in galleria e io non voglio che sia fatta –