大家在做安卓应用的时候  经常要从网络中获取图片 都是通过URL去获取 可是如果本地有图片数据 从本地获取数据不更加快一些  自己在工作中遇到这个问题 所以采用了一个URL和本地图片的一个映射关系  先从本地区获取 假如本地没有再从网络中获取  本方法考虑到多线程问题  欢迎大家一起共同探讨!

public class PictureLibrary {
    /*
     * 图片库的操作
     */

File file;

URL url;
    HttpURLConnection conn;
    InputStream is;
    FileOutputStream fos;

private Lock lock = new ReentrantLock();

private Condition downFile = lock.newCondition();

// 通过URL将数据下载到本地操作
    private String toLocalFile(String strURL) {
        String fileName = Utils.getFileName(strURL);
        String path = Environment.getExternalStorageDirectory() + "/"
                + EcologicalTourism.FILE_PATH + "/images/" + fileName;

return path;
    }

// 通过URL将数据下载到本地临时文件中
    private String toLocalFileTemp(String strURL) {
        String s = Utils.getFileName(strURL);
        String fileName = s+"temp";
        String path_url = Environment.getExternalStorageDirectory() + "/"
                + EcologicalTourism.FILE_PATH + "/tempimages/" + fileName;

return path_url;
    }

/*
     * 保存图片到本地,并返回本地url(此函数是阻塞的)
     * main
     * @参数:strURL,参数为图片的URL.返回值:该图片在本地SD卡暂存的位置
     * 函数的工作是负责将图片从互联网上取得,存在本地存储中,并返回本地存储的文件路径,供调用者直接使用。如果文件已经存在本地,直接返回
     * 如果文件未在本地,则直接从服务器下载,函数阻塞。
     */
    public String getReadSD(String strURL) {
        Log.i("test", "拿到网络的地址是:" + strURL);
        String strLocalFile = toLocalFile(strURL);  //k:把服务器URL转换为本地URL
        String strLocalFileTemp = toLocalFileTemp(strURL); //k:把服务器URL转换为本地临时URL
        while (true) {
            File file = new File(strLocalFile);
            Log.i("test", "本地文件是:" + strLocalFile);
            File tfile = new File(strLocalFileTemp);
            Log.i("test", "临时文件是:" + strLocalFileTemp);
            // 1上锁
            lock.lock();

if (file.exists()) {
                // 2if 本地文件存在
                // 解锁
                // 返回本地路径
                lock.unlock();
                Log.i("test", "返回本地路径:" + file);
                return strLocalFile;
            } else if (tfile.exists()) {
                // if 对应的暂存文件存在
                // 解锁
                lock.unlock();
                try {
                    // 睡眠
                    downFile.await();
                } catch (Exception e) {
                     e.printStackTrace();
                    Log.i("test", "e 出现了异常1" + e);
                }

} else {
                try {
                    // 创建对应的暂存文件
                    tfile.createNewFile();
                } catch (IOException e) {
                    Log.i("test", "e 出现了异常2" + e);

}
                // 解锁
                lock.unlock();
                // 下载文件内容到暂存文件中
                downURL2(strURL, strLocalFile);
                // 上锁
                lock.lock();
                // 修改暂存文件名字为本地文件名
                tfile.renameTo(file);
                // 解锁
                lock.unlock();
            }

}
    }

private void downURL2(String strURL, String strLocalFileTemp) {
        // TODO Auto-generated method stub
        URL url;
        try {
            url = new URL(strURL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            if (conn.getResponseCode() == 200) {
                    InputStream is = conn.getInputStream();
                    FileOutputStream fos = new FileOutputStream(strLocalFileTemp);
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = is.read(buffer)) != -1) {
                            fos.write(buffer, 0, len);
                    }
                    is.close();
                    fos.close();
                    // 返回一个URI对象
            }
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }

/*
     * 阻塞式下载url到文件 toFile中
     */
    private boolean downURL(String strURL, String toFile) {
       
        URL url;
        try {
            url = new URL(strURL);
            HttpURLConnection httpUrl = (HttpURLConnection) url
                    .openConnection();
            httpUrl.setRequestMethod("GET");
            int fileSize = httpUrl.getContentLength();// 文件大小
            httpUrl.disconnect();// 关闭连接
            int threadSize = 6;// 默认设置6个线程
            threadSize = fileSize % threadSize == 0 ? threadSize
                    : threadSize + 1;
            int currentSize = fileSize / threadSize; // 每条线程下载大小

String dowloadir = Environment.getExternalStorageDirectory() + "/"
                    + EcologicalTourism.FILE_PATH + "/images/";

File dir = new File(dowloadir);

if (!dir.exists()) {
                dir.mkdirs();
            }
            File file = new File(dir, toFile);
            RandomAccessFile randomFile = new RandomAccessFile(file, "rw");
            randomFile.setLength(fileSize);// 指定 file 文件的大小
            for (int i = 0; i < threadSize; i++) {
                int startposition = i * currentSize;// 每条线程开始写入文件的位置
                RandomAccessFile threadFile = new RandomAccessFile(file, "rw");
                Log.i("syso", "toFile的内容是:" + toFile);
                threadFile.seek(startposition);
                new DownLoadThread(i, currentSize, threadFile, startposition,
                        url).start();
            }

} catch (Exception e) {
            e.printStackTrace();
            Log.i("syso", "download下载失败" + e);
        }

return true;
    }

/**
     * 实现线程下载
     *
     */
    private static class DownLoadThread extends Thread {
        @SuppressWarnings("unused")
        private int threadId;// 线程编号
        private int currentSize;// 每条线程的大小
        private RandomAccessFile threadFile; // 每条线程 要写入文件类
        private int startposition;// 每条线程开始写入文件的位置
        private URL url;  //网络地址

public DownLoadThread(int threadId, int currentSize,
                RandomAccessFile threadFile, int startposition, URL url) {
            this.threadId = threadId;
            this.currentSize = currentSize;
            this.threadFile = threadFile;
            this.startposition = startposition;
            this.url = url;
        }

public void run() {
            try {
                HttpURLConnection httpUrl = (HttpURLConnection) url
                        .openConnection();
                httpUrl.setRequestMethod("GET");
                httpUrl.setRequestProperty("range", "bytes=" + startposition
                        + "-");// 指定服务器的位置
                InputStream is = httpUrl.getInputStream();
                byte[] data = new byte[1024];
                int len = -1;
                int threadFileSize = 0;
                while ((threadFileSize < currentSize)
                        && ((len = is.read(data)) != -1)) {
                    threadFile.write(data, 0, len);
                    threadFileSize += len;
                }
                httpUrl.disconnect();
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    
    
    /**
    * 从本缓存中获取图片
    */
    public  Bitmap getBitmapFromCache(String imageURL) {
//        String bitmapName = imageURL.substring(imageURL.lastIndexOf("/") + 1);
        String bitmapName = Utils.getFileName(imageURL);
        File cacheDir = new File(Environment.getExternalStorageDirectory() + "/"
                + EcologicalTourism.FILE_PATH + "/images/");    
        File[] cacheFiles = cacheDir.listFiles();    
        int i = 0;    
        if(null!=cacheFiles){  
            for(; i<cacheFiles.length;i++){    
                if(bitmapName.equals(cacheFiles[i].getName())){    
                    break;    
                }    
            }    
                
            if(i < cacheFiles.length)    
            {    
                return BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + "/"
                        + EcologicalTourism.FILE_PATH + "/images/" + bitmapName);    
            }
          
        }
        return null;  
    }

[置顶] android 图片库的封装的更多相关文章

  1. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

  2. [置顶] Android 状态栏那些小坑?

    背景:因为之前老板上次问我我们的app能不能自定义上面的状态栏我说可以啊!当时没管,今天试了下果然很多坑,之前github上也有很多大佬写了一个开源库有兴趣的可以点进去看下支持DrawLayout沉侵 ...

  3. [置顶] Android AlarmManager实现不间断轮询服务

    在消息的获取上是选择轮询还是推送得根据实际的业务需要来技术选型,例如对消息实时性比较高的需求,比如微博新通知或新闻等那就最好是用推送了.但如果只是一般的消息检测比如更新检查,可能是半个小时或一个小时一 ...

  4. [置顶] [Android源码分析]inquiry result引起的上层变化分析

    在上一篇文章中,我们详细分析了android是如何解析蓝牙反馈上来的搜索到的设备信息,本文将会继续分析这些信息到了上层之后是如何处理. 8.inquiry result引起的上层变化 我们知道inqu ...

  5. [置顶] android之存储篇_SQLite数据库_让你彻底学会SQLite的使用

    SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中 ...

  6. [置顶] Android四大组件之BroadcastReceiver

    Android四大组件之BroadcastReceiver Broadcast Receiver 广播接收器,是一种负责接收广播消息并对消息做出响应的组件,和Service一样并不提供与用户交互的UI ...

  7. [置顶] Android开发之Thread类分析

    在我们Linux系统中创建线程函数为:pthread_create(),在Android中我们为线程封装了一个类Thread,实际调用的还是pthread_create() 当我们想创建线程的时候,只 ...

  8. [置顶] Android Sensor系统剖析(4.0)(下)

    Author:Harish_hu@qq.com 由于现在电脑上只有4.0的代码,考虑到代码差别也不大,所以下部分,就基于4.0来分析.  3:SensorManager 上一部分说过,开机后,syst ...

  9. [置顶] Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...

随机推荐

  1. 谈谈oracle中的临时表

    --------------------创建临时表 临时保存从xml字符串解析来的数据--------------------------- 会话级别临时表SQL> create global ...

  2. [转]Delphi I/O Errors

    The following are the Windows API (and former DOS) IO errors, which are also the IO errors often ret ...

  3. mysql锁死的现象判断

    一般发生表锁死这种低级问题,就有两种情况:1.程序员水平太菜,2.程序逻辑错误. 一旦发生系统会出现超时,关键是有可能你看不到正在活动的php进程,而系统的慢查询日志也不会记录,只能通过show fu ...

  4. window下配置SSH连接GitHub、GitHub配置ssh key(转)

    转自:http://jingyan.baidu.com/article/a65957f4e91ccf24e77f9b11.html 此经验分两部分: 第一部分介绍:在windows下通过msysGit ...

  5. JS 打字机效果

    请点我,查看效果 我送过你礼物 试过对你不管不顾 我挂过你电话 也曾为你哭到沙哑 我曾经为你去学做过晚餐 曾觉得你的关心太烦 也曾为你起得很早 试过狠心把你甩掉 试过偷偷拍你的微笑 也曾经把你电话删掉 ...

  6. js 去除字符串开头或者前几个字符。slice 也可以用于截取某一部分

    摘草自w3 slice() 方法可从已有的数组中返回选定的元素. 语法 arrayObject.slice(start,end) 参数 描述 start 必需.规定从何处开始选取.如果是负数,那么它规 ...

  7. 使用Raphael 画图(一) 基本图形 (javascript)

    Raphael是什么? Raphael 是一个用于在网页中绘制矢量图形的 Javascript 库.它使用 SVG W3C 推荐标准和 VML 作为创建图形的基础,你可以通过 JavaScript 操 ...

  8. Python 的“+”和append在添加字符串时候的区别

    对于一个空的Python列表,往后添加内容有很多种,其中两种一个是用“+”直接添加内容,另外一种是Listname.append(x)来添加内容 其中,如果处理字符串 在使用“+”的时候,会将字符串拆 ...

  9. 那些年被我坑过的Python——道阻且长(第五章实用模块讲解)

    random模块 我的随机验证吗程序: 首先保证了字母和数字出现的概率是50% VS 50%,其次是可以订制输出多少位 def Captcha(size): Captcha_list = [] for ...

  10. 【C语言】严格区分大小写

    C语言严格区分大小写 一.相关基础知识 二.具体内容 C语言严格区分大小写: 如: int为关键字,INT则为用户标识符,即可定义int INT;   int INt;   int Int;  cha ...