2011-05-03 76 views
1

我有这个类从网上下载图像,我需要有人帮助我修改我的代码,以便下载的图像保存在SD卡上。由于我从互联网上获取这些代码,并且我是一个新手,因此我很难将其优化为缓存。Android:下载图像并将它们保存为缓存

我愿意接受任何形式的解决方案。 非常感谢。

public class ImageThreadLoader { 
    private static final String TAG = "ImageThreadLoader"; 

    // Global cache of images. 
    // Using SoftReference to allow garbage collector to clean cache if needed 
    private final HashMap<String, SoftReference<Bitmap>> Cache = new HashMap<String, SoftReference<Bitmap>>(); 

    private final class QueueItem { 
     public URL url; 
     public ImageLoadedListener listener; 
    } 
    private final ArrayList<QueueItem> Queue = new ArrayList<QueueItem>(); 

    private final Handler handler = new Handler(); // Assumes that this is started from the main (UI) thread 
    private Thread thread; 
    private QueueRunner runner = new QueueRunner();; 

    /** Creates a new instance of the ImageThreadLoader */ 
    public ImageThreadLoader() { 
     thread = new Thread(runner); 
    } 

    /** 
    * Defines an interface for a callback that will handle 
    * responses from the thread loader when an image is done 
    * being loaded. 
    */ 
    public interface ImageLoadedListener { 
     public void imageLoaded(Bitmap imageBitmap); 
    } 

    /** 
    * Provides a Runnable class to handle loading 
    * the image from the URL and settings the 
    * ImageView on the UI thread. 
    */ 
    private class QueueRunner implements Runnable { 
     public void run() { 
      synchronized(this) { 
       while(Queue.size() > 0) { 
        final QueueItem item = Queue.remove(0); 

        // If in the cache, return that copy and be done 
        if(Cache.containsKey(item.url.toString()) && Cache.get(item.url.toString()) != null) { 
         // Use a handler to get back onto the UI thread for the update 
         handler.post(new Runnable() { 
          public void run() { 
           if(item.listener != null) { 
            // NB: There's a potential race condition here where the cache item could get 
            //  garbage collected between when we post the runnable and it's executed. 
            //  Ideally we would re-run the network load or something. 
            SoftReference<Bitmap> ref = Cache.get(item.url.toString()); 
            if(ref != null) { 
             item.listener.imageLoaded(ref.get()); 
            } 
           } 
          } 
         }); 
        } else { 
         final Bitmap bmp = readBitmapFromNetwork(item.url); 
         if(bmp != null) { 
          Cache.put(item.url.toString(), new SoftReference<Bitmap>(bmp)); 

          // Use a handler to get back onto the UI thread for the update 
          handler.post(new Runnable() { 
           public void run() { 
            if(item.listener != null) { 
             item.listener.imageLoaded(bmp); 
            } 
           } 
          }); 
         } 

        } 

       } 
      } 
     } 
    } 

    /** 
    * Queues up a URI to load an image from for a given image view. 
    * 
    * @param uri The URI source of the image 
    * @param callback The listener class to call when the image is loaded 
    * @throws MalformedURLException If the provided uri cannot be parsed 
    * @return A Bitmap image if the image is in the cache, else null. 
    */ 
    public Bitmap loadImage(final String uri, final ImageLoadedListener listener) throws MalformedURLException { 
     // If it's in the cache, just get it and quit it 
     if(Cache.containsKey(uri)) { 
      SoftReference<Bitmap> ref = Cache.get(uri); 
      if(ref != null) { 
       return ref.get(); 
      } 
     } 

     QueueItem item = new QueueItem(); 
     item.url = new URL(uri); 
     item.listener = listener; 
     Queue.add(item); 

     // start the thread if needed 
     if(thread.getState() == State.NEW) { 
      thread.start(); 
     } else if(thread.getState() == State.TERMINATED) { 
      thread = new Thread(runner); 
      thread.start(); 
     } 
     return null; 
    } 

    /** 
    * Convenience method to retrieve a bitmap image from 
    * a URL over the network. The built-in methods do 
    * not seem to work, as they return a FileNotFound 
    * exception. 
    * 
    * Note that this does not perform any threading -- 
    * it blocks the call while retrieving the data. 
    * 
    * @param url The URL to read the bitmap from. 
    * @return A Bitmap image or null if an error occurs. 
    */ 
    public static Bitmap readBitmapFromNetwork(URL url) { 
     InputStream is = null; 
     BufferedInputStream bis = null; 
     Bitmap bmp = null; 
     try { 
      URLConnection conn = url.openConnection(); 
      conn.connect(); 
      is = conn.getInputStream(); 
      bis = new BufferedInputStream(is); 
      bmp = BitmapFactory.decodeStream(bis); 
     } catch (MalformedURLException e) { 
      Log.e(TAG, "Bad ad URL", e); 
     } catch (IOException e) { 
      Log.e(TAG, "Could not get remote ad image", e); 
     } finally { 
      try { 
       if(is != null) 
        is.close(); 
       if(bis != null) 
        bis.close(); 
      } catch (IOException e) { 
       Log.w(TAG, "Error closing stream."); 
      } 
     } 
     return bmp; 
    } 

} 

回答

5

您可以存储使用位图类的压缩方法的位图:here

我自己的代码是:

FileOutputStream os = null; 
try { 
    os = new FileOutputStream(
      new File( 
        android.os.Environment.getExternalStorageDirectory().getAbsolutePath(), 
       fileName)); 

    bitmap.compress(Bitmap.CompressFormat.JPEG, 90, os); 
} catch (FileNotFoundException e) { 
    e.printStackTrace(); 
} 
finally { 
    if (os != null) { 
     try { 
      os.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

它允许你写SD卡上的位图。

要打开存储在SD卡上的位图使用decodeFile()方法从BitmapFactory类:here

还应验证是否可以读取和使用SD卡上写: android.os.environment.getExternalStorageDirectory().canRead()android.os.environment.getExternalStorageDirectory().canWrite() 方法。

+0

我在哪种方法来实现你的代码我有一个类似的问题 – 2013-01-31 03:17:46