[置顶] android 图片库的封装
大家在做安卓应用的时候 经常要从网络中获取图片 都是通过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 图片库的封装的更多相关文章
- [置顶] Android开发笔记(成长轨迹)
分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...
- [置顶]
Android 状态栏那些小坑?
背景:因为之前老板上次问我我们的app能不能自定义上面的状态栏我说可以啊!当时没管,今天试了下果然很多坑,之前github上也有很多大佬写了一个开源库有兴趣的可以点进去看下支持DrawLayout沉侵 ...
- [置顶] Android AlarmManager实现不间断轮询服务
在消息的获取上是选择轮询还是推送得根据实际的业务需要来技术选型,例如对消息实时性比较高的需求,比如微博新通知或新闻等那就最好是用推送了.但如果只是一般的消息检测比如更新检查,可能是半个小时或一个小时一 ...
- [置顶] [Android源码分析]inquiry result引起的上层变化分析
在上一篇文章中,我们详细分析了android是如何解析蓝牙反馈上来的搜索到的设备信息,本文将会继续分析这些信息到了上层之后是如何处理. 8.inquiry result引起的上层变化 我们知道inqu ...
- [置顶] android之存储篇_SQLite数据库_让你彻底学会SQLite的使用
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中 ...
- [置顶] Android四大组件之BroadcastReceiver
Android四大组件之BroadcastReceiver Broadcast Receiver 广播接收器,是一种负责接收广播消息并对消息做出响应的组件,和Service一样并不提供与用户交互的UI ...
- [置顶] Android开发之Thread类分析
在我们Linux系统中创建线程函数为:pthread_create(),在Android中我们为线程封装了一个类Thread,实际调用的还是pthread_create() 当我们想创建线程的时候,只 ...
- [置顶] Android Sensor系统剖析(4.0)(下)
Author:Harish_hu@qq.com 由于现在电脑上只有4.0的代码,考虑到代码差别也不大,所以下部分,就基于4.0来分析. 3:SensorManager 上一部分说过,开机后,syst ...
- [置顶] Android图片异步加载之Android-Universal-Image-Loader
将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...
随机推荐
- eclipse中更改默认编码格式
更改过程如下: (1)window->preferences->general->content Types, 选中java class file修改default encoding ...
- java基础易错点总结(一)
子类继承父类表示子类比他的父类包含更多的信息和方法 子类调用重载的构造方法时会调用父类的构造方法,super();一般如果不写的话会隐式的调用,而且每次调用都在所有语句之前. 在函数中,使用父类的地方 ...
- 【HDU4348】【主席树】To the moon
Problem Description BackgroundTo The Moon is a independent game released in November 2011, it is a r ...
- Java常量和变量
1.Java运行原理 编译+解释型语言: 程序代码经编译后转换为一种称为java字节码(.class文件)的中间语言 file.java--->Class.class java虚拟机JVM将字节 ...
- Fatal error: Class 'ZipArchive' not found的解决办法
今天在Linux底下编写导出EXCEL文件并显示输出时,抛出“ZipArchive library is not enabled” 的异常.而我在本地的windows下的代码则是运行正常的. 原因是: ...
- 利用Python读取Matlab的Mat文件内容
手头有别人写的Matlab程序,其中用到了Mat文件.现在不想安装Matlab,却又想读取Mat文件内容,该怎么办呢? 感谢scipy!!! import scipy.io data = scipy. ...
- 单个ViewController支持横屏,其他全竖屏方法-b
如果项目中用了navigationViewController, 那么就应该新建一个uinavigationViewController的子类,然后在这个类里面写上下面的代码,在使用的时候就用自定义的 ...
- Zephyr-MQTT
Zephyr OS 支持MQTT协议,其源码目录在: # cd /zephyr-/samples/net/paho_mqtt_clients/publisher/ # cd /zephyr-1.5.0 ...
- [待续]Async in C# 1
异步.异步是在.net .45里面提供的一个新的方法 它主要用在.三个方面 1.网络访问 2.磁盘访问 3.延迟很长时间的步骤 它主要有2个关键字 Async Await Async 怎么工作 d ...
- sql restore mode
refer : https://msdn.microsoft.com/en-us/library/ms189272.aspx SELECT name, recovery_model_desc FROM ...