安卓图片下载及存储

网上找到一个下载图片的工具类,下载到的图片是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

安卓图片下载及存储的相关文章

安卓图片的异步请求及使用LruCache缓存和手机内存两层存储图片,避免重新加载页面带来的重新请求

看到网友的一片技术博客讲解了LruCache的使用,我把它加到了我的项目中,但是加入断点发现,列表上下滑动时,确实可以不用重新加载图片,但是重新打开这个activity或者重新启动应用,LruCache的缓存都不再存在,而需要重新联网下载,所有我对这个方法加以改进,加入了一层往手机内存存储图片的过程. 这样的话,使用图片时,先从LruCache中加载,如果LruCache中不存在该图片资源的话,再从手机存储中进行加载,如果同样不存在,则先显示一个默认图片. 另一方面,我的项目使用图片的是list

iOS利用SDWebImage图片下载缓存

一.我们先来了解一下SDWebImage的使用: 1.导入框架,引入头文件: #import "UIImageView+WebCache.h" 也可以直接使用CocoaPods来引入和管理 (OC 如下) platform :ios, '7.0' pod 'SDWebImage', '~>3.8' (swift)并且要确保添加了use_frameworks,iOS版本为8.0+ platform :ios, '8.0' use_frameworks! 2.图片下载并缓存方法: /

Scrapy基础————图片下载后将本地路径添加到Item中

前边讲到简单的图片下载,但是怎样将图片的本地路径和存储在Item中的数据对应起来,所以本篇博文讲解到如何将 本地的下载后的图片路径写入到Item中 思路:自定义pipline,多加个管道,该管道继承下载图片的类,并重写与Item 交互的方法,从众提取到本地路径,并返回这个Item交给下一个pipline管道 具体代码: 先导入 from scrapy.pipelines.images import ImagesPipeline 1 #补充Item的字段,将文章列表页的图片下载下来,并将图片的路径

Android图片下载以及缓存框架

实际开发中进行图片下载以及缓存的框架 介绍一下开发中常见图片加载框架的使用和对比一下优缺点. 1.Picasso 框架 在Android中开发,常需要从远程获取图片并显示在客户端,当然我们可以使用原生HttpURLConnection和AsyncTask等操作来完成,但并不推荐,因为这样不仅需要我们编写大量的代码, 还需要处理缓存和下载管理等,最好自己封装成库或者采用第三方库: 使用HttpUrlConnection和AsyncTask实现远程图片下载: 使用HttpUrlConnection和

picasso-强大的Android图片下载缓存库

编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! picasso是Square公司开源的一个Android图形缓存库,地址http://square.github.io/picasso/,可以实现图片下载和缓存功能.仅仅只需要一行代码就能完全实现图片的异步加载: Picasso.with(context).load("http://i.imgur.com/

SDWebImage异步的图片下载+缓存

SDWebImage托管在github上.https://github.com/rs/SDWebImage 这个类库提供一个UIImageView类别以支持加载来自网络的远程图片.具有缓存管理.异步下载.同一个URL下载次数控制和优化等特征.使用示范的代码: UITableView使用UIImageView+WebCache类(基本应用,UIImageView的一个category) 前提#import导入UIImageView+WebCache.h文件,然后在tableview的cellFor

多图片下载、缓存及SDWebImage

首先介绍一下如果不使用SDWebImage,自己写代码实现多图片的下载及缓存的思路: 这里只提供了一个思路作为了解,因为多图片下载.缓存的实现,使用三方SDWebImage特别的简单,以后开发过程中也是使用这种方式,不用自己写代码,所以这里只提供一个思路,关于SDWebImage的使用将在最后进行解释: 1 //声明一个用来缓存图片的可变字典 imagesDict,字典的value值为图片,key值为图片网址 2 //声明一个字典用来存储操作对象value值为(NSOperation *oper

图片下载本地缓存时间戳显示图片方法

来源:http://ask.dcloud.net.cn/article/511 源码下载 参考文章http://ask.dcloud.net.cn/article/256http://ask.dcloud.net.cn/article/397 说明:为了方便,里面使用的图片来源是从上面文章中的源码项目获取的.说明:参考了上面文章中的思路,然后自己重新写了一个较为完整的图片本地缓存显示工具.功能1.第一次显示图片时下载到本地,然后之后如果本地存在缓存(根据url),则显示本地缓存的图片2. 基于p

多线程实现多图片下载1

展示效果如下: 大家可以看到这个界面很简单,其实就是UITableView的布局, 但是难点是在于如何从网上下载这些图片,下载之后应如何进行存储! 我们一步一步进行解析,先从单线程(主线程)进行多图片下载 我们布局上的文字及图片的地址从plist文件中进行读取 根据结构,我们自定义一个数据模型文件 DDZApp.h #import <Foundation/Foundation.h> @interface DDZApp : NSObject //图标 @property (nonatomic,s