网上找到一个下载图片的工具类,下载到的图片是Drawable类型的。
1 package com.cn.gordon.exhibition.walk.utils; 2 3 import java.io.InputStream; 4 import java.lang.ref.SoftReference; 5 import java.net.URL; 6 import java.net.URLConnection; 7 import java.util.HashMap; 8 import java.util.concurrent.BlockingQueue; 9 import java.util.concurrent.LinkedBlockingQueue; 10 import java.util.concurrent.RejectedExecutionHandler; 11 import java.util.concurrent.ThreadPoolExecutor; 12 import java.util.concurrent.TimeUnit; 13 14 import android.graphics.drawable.Drawable; 15 import android.os.Handler; 16 import android.os.Looper; 17 /** 18 * 加载图片类 19 * @author jialg 20 * 21 */ 22 public class AsyncImageLoader { 23 private static final String TAG = "AsyncImageLoader"; 24 private ThreadPoolExecutor mPoolExecutor; 25 private HashMap<String, SoftReference<Drawable>> imageCache; 26 private Handler mMainThreadHandler; 27 28 /** 29 * 创建一个异步图片加载器,默认最大5个工作线程,最大等待队列20 30 */ 31 public AsyncImageLoader() { 32 this(5, 20); 33 } 34 35 /** 36 * 创建一个异步图片加载器,当等待下载的图片超过设置的最大等待数量之后,会从等待队列中放弃一个最早加入队列的任务 37 * 38 * @param maxPoolSize 最大工作线程数 39 * @param queueSize 最大等待数 40 */ 41 public AsyncImageLoader(int maxPoolSize, int queueSize) { 42 this(2, maxPoolSize, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(queueSize), 43 new ThreadPoolExecutor.DiscardOldestPolicy()); 44 } 45 46 /** 47 * 自定义线程池的加载器,请参考:{@link ThreadPoolExecutor} 48 * 49 * @param corePoolSize 50 * @param maximumPoolSize 51 * @param keepAliveTime 52 * @param unit 53 * @param workQueue 54 * @param handler 55 */ 56 public AsyncImageLoader(int corePoolSize, int maximumPoolSize, long keepAliveTime, 57 TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { 58 imageCache = new HashMap<String, SoftReference<Drawable>>(); 59 mPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, 60 workQueue, handler); 61 mMainThreadHandler = new Handler(Looper.getMainLooper()); 62 } 63 64 /** 65 * 异步加载一张图片 66 * 67 * @param imageUrl 68 * @param imageCallback 69 */ 70 public void loadDrawable(final String imageUrl, final ImageCallback imageCallback) { 71 if (imageCache.containsKey(imageUrl)) { 72 SoftReference<Drawable> softReference = imageCache.get(imageUrl); 73 Drawable drawable = softReference.get(); 74 if (drawable != null) { 75 imageCallback.onLoaded(drawable); 76 return; 77 } 78 } 79 LoadImageTask task = new LoadImageTask(imageUrl, this, mMainThreadHandler, imageCallback); 80 mPoolExecutor.execute(task); 81 } 82 83 /** 84 * 停止线程池运行,停止之后,将不能在继续调用 {@link #loadDrawable(String, ImageCallback)} 85 */ 86 public void shutdown() { 87 mPoolExecutor.shutdown(); 88 imageCache.clear(); 89 } 90 91 private void cache(String url, Drawable drawable) { 92 imageCache.put(url, new SoftReference<Drawable>(drawable)); 93 } 94 95 /** 96 * 下载任务 97 * 98 */ 99 private static final class LoadImageTask implements Runnable { 100 101 private Handler mHandler; 102 private ImageCallback mCallback; 103 private AsyncImageLoader mLoader; 104 private String mPath; 105 106 /** 107 * @param imgPath 要下载的图片地址 108 * @param loader 图片加载器 109 * @param handler 主线程Handler 110 * @param imageCallback 图片加载回调 111 */ 112 public LoadImageTask(String imgPath, AsyncImageLoader loader, Handler handler, 113 ImageCallback imageCallback) { 114 this.mHandler = handler; 115 this.mPath = imgPath; 116 this.mLoader = loader; 117 this.mCallback = imageCallback; 118 } 119 120 @Override 121 public void run() { 122 URL url; 123 InputStream is = null; 124 try { 125 url = new URL(mPath); 126 URLConnection conn = url.openConnection(); 127 conn.connect(); 128 is = conn.getInputStream(); 129 final Drawable drawable = Drawable.createFromStream(is, "src"); 130 mLoader.cache(mPath, drawable); 131 mHandler.post(new Runnable() { 132 133 @Override 134 public void run() { 135 mCallback.onLoaded(drawable); 136 } 137 }); 138 } catch (final Exception e) { 139 mHandler.post(new Runnable() { 140 141 @Override 142 public void run() { 143 mCallback.onError(e); 144 } 145 }); 146 } 147 } 148 } 149 150 /** 151 * 回调接口,在主线程中运行 152 * 153 */ 154 public static interface ImageCallback { 155 /** 156 * 加载成功 157 * 158 * @param imageDrawable 下载下来的图片 159 */ 160 public void onLoaded(Drawable drawable); 161 162 /** 163 * 加载失败 164 * 165 * @param e 异常 166 */ 167 public void onError(Exception e); 168 } 169 }
图片下载之后,要进行存储,存储的类型是Bitmap,所以要将图片先转成BitmapDrawable,然后再转成Bitmap,运用上面的工具类进行图片的下载,并进行保存。
public class EntryActivity extends Activity { private AsyncImageLoader asyncImageLoader; private static String ALBUM_PATH = getSDPath() + java.io.File.separator + "exhibition_walk"; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.walkmain); asyncImageLoader= new AsyncImageLoader(); init(); } private void init(){ asyncImageLoader.loadDrawable(urlStr, new ImageCallback(){ @Override public void onLoaded(Drawable imageDrawable) { if(imageDrawable != null){ v1.setImageDrawable(imageDrawable); BitmapDrawable draw = (BitmapDrawable) imageDrawable; final Bitmap bitmap = draw.getBitmap(); try { if (bitmap!=null) { Toast.makeText(EntryActivity.this, "下载的图片可用", Toast.LENGTH_SHORT).show(); savePicture(bitmap, System.currentTimeMillis()+".jpg"); }else{ Toast.makeText(EntryActivity.this, "下载的图片不可用", Toast.LENGTH_SHORT).show(); } } catch (IOException e) { e.printStackTrace(); } } } @Override public void onError(Exception e) { } }); } private void savePicture(Bitmap bitmap,String fileName) throws IOException{ File dirFile = new File(ALBUM_PATH); if(!dirFile.exists()){ dirFile.mkdirs(); Toast.makeText(EntryActivity.this, "创建文件夹", Toast.LENGTH_SHORT).show(); } File myCaptureFile = new File(ALBUM_PATH + java.io.File.separator +fileName); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile)); bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos); bos.flush(); bos.close(); } /** * 获取sd卡的路径 * * @return 路径的字符串 */ public static String getSDPath() { File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在 if (sdCardExist) { sdDir = Environment.getExternalStorageDirectory();// 获取外存目录 } return sdDir.toString(); } }
最后,图片存储到sd卡上,要进行权限的声明:
1 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 2 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
时间: 2024-11-04 19:33:34