安卓中获取网络图片,生成缓存

  用安卓手机,因为手机流量的限制,所以我们在做应用时,要尽量为用户考虑,尽量少耗点用户的流量,而在应用中网络图片的显示无疑是消耗流量最大的,所以我们可以采取压缩图片或者将图片进行缓存,使图片只需要获取一次即可。

获取网络图片,并进行压缩

public static Bitmap returnBitMapWego(String url) {
URL myFileUrl = null;
Bitmap bitmap = null;
try {
myFileUrl = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
Options op = new Options();
op.inSampleSize = 2;//压缩的倍数
op.inJustDecodeBounds = false;
Rect rect = new Rect(0, 0, 0, 0);
bitmap = BitmapFactory.decodeStream(is, rect, op);
is.close();
} catch (IOException e) {
// e.printStackTrace();
bitmap = null; }
return bitmap;
}

异步获取网络图片并进行缓存

package com.jijie.yibu;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.net.ConnectivityManager;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView; public class LogoLoader { public static final String CACHE_DIR = "/图片在手机中的保存路径";
// 缓存下载过的图片的Map
private Map<String, SoftReference<Bitmap>> caches;
// 任务队列
private List<Task> taskQueue;
private boolean isRunning = false;
private int width, height;
private Context ctx; public LogoLoader(Context ctx) {this.ctx = ctx;
// 初始化变量
caches = new HashMap<String, SoftReference<Bitmap>>();
taskQueue = new ArrayList<LogoLoader.Task>();
// 启动图片下载线程
isRunning = true;
new Thread(runnable).start();
} /**
*
* @param imageView
* 需要延迟加载图片的对象
* @param url
* 图片的URL地址
* @param resId
* 图片加载过程中显示的图片资源
*/
public void showImageAsyn(ImageView imageView, String url, int resId) {
imageView.setTag(url);
Bitmap bitmap = loadImageAsyn(url, getImageCallback(imageView, resId)); if (bitmap == null) {
// imageView.setImageResource(resId);
// imageView.setBackgroundResource(resId);
} else {
// imageView.setImageBitmap(bitmap);
BitmapDrawable bd = new BitmapDrawable(bitmap);
imageView.setBackgroundDrawable(bd);
}
} public Bitmap loadImageAsyn(String path, ImageCallback callback) {
// 判断缓存中是否已经存在该图片
if (caches.containsKey(path)) {
// 取出软引用
SoftReference<Bitmap> rf = caches.get(path);
// 通过软引用,获取图片
Bitmap bitmap = rf.get();
// 如果该图片已经被释放,则将该path对应的键从Map中移除掉
if (bitmap == null) {
caches.remove(path);
} else {
// 如果图片未被释放,直接返回该图片 return bitmap;
}
} else {
// 如果缓存中不常在该图片,则创建图片下载任务
Task task = new Task();
task.path = path;
task.callback = callback; if (!taskQueue.contains(task)) {
taskQueue.add(task);
// 唤醒任务下载队列
synchronized (runnable) {
runnable.notify();
}
}
} // 缓存中没有图片则返回null
return null;
} /**
*
* @param imageView
* @param resId
* 图片加载完成前显示的图片资源ID
* @return
*/
private ImageCallback getImageCallback(final ImageView imageView,
final int resId) {
return new ImageCallback() { public void loadImage(String path, Bitmap bitmap) {
if (path.equals(imageView.getTag().toString())) {
// imageView.setImageBitmap(bitmap);
BitmapDrawable bd = new BitmapDrawable(bitmap);
imageView.setBackgroundDrawable(bd); } else {
// imageView.setImageResource(resId);
// imageView.setBackgroundResource(resId);
}
}
};
} private Handler handler = new Handler() { @Override
public void handleMessage(Message msg) {
// 子线程中返回的下载完成的任务
Task task = (Task) msg.obj;
// 调用callback对象的loadImage方法,并将图片路径和图片回传给adapter
task.callback.loadImage(task.path, task.bitmap);
} }; private Runnable runnable = new Runnable() { public void run() {
while (isRunning) {
// 当队列中还有未处理的任务时,执行下载任务
while (taskQueue.size() > 0) {
// 获取第一个任务,并将之从任务队列中删除
Task task = taskQueue.remove(0);
// 将下载的图片添加到缓存 if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)
&& !checkNetWorkStatus()) {
File file = new File("/mnt/sdcard/jijie/imagecache/"
+ getFileName(task.path));
if (file.exists() && file.length() > 100) { try {
task.bitmap = PicUtil
.getRoundedCornerBitmap(
BitmapFactory
.decodeFile("/mnt/sdcard/jijie/imagecache/"
+ getFileName(task.path)),
10); } catch (OutOfMemoryError err) {
}
}
} else if (checkNetWorkStatus()) { task.bitmap = PicUtil.getRoundedCornerBitmap(
PicUtil.returnBitMap(task.path), 10);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); task.bitmap.compress(Bitmap.CompressFormat.PNG,
100, baos); Write(task.path, baos.toByteArray());
} catch (Exception e) { } } // task.bitmap=PicUtil.getbitmapAndwrite(task.path);
// caches.put(task.path, new
// SoftReference<Bitmap>(task.bitmap));
if (handler != null) {
// 创建消息对象,并将完成的任务添加到消息对象中
Message msg = handler.obtainMessage();
msg.obj = task;
// 发送消息回主线程
handler.sendMessage(msg);
}
} // 如果队列为空,则令线程等待
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}; // 回调接口
public interface ImageCallback {
void loadImage(String path, Bitmap bitmap);
} class Task {
// 下载任务的下载路径
String path;
// 下载的图片
Bitmap bitmap;
// 回调对象
ImageCallback callback; @Override
public boolean equals(Object o) {
Task task = (Task) o;
return task.path.equals(path);
}
} public void Write(String imageurl, byte[] b) {
File cacheFile = FileUtil.getCacheFile(imageurl); BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(cacheFile)); bos.write(b, 0, b.length);
bos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static String getFileName(String path) {
int index = path.lastIndexOf("/");
return path.substring(index + 1);
} private boolean checkNetWorkStatus() {
boolean netSataus = false;
ConnectivityManager cwjManager = (ConnectivityManager) ctx
.getSystemService(Context.CONNECTIVITY_SERVICE);
cwjManager.getActiveNetworkInfo();
if (cwjManager.getActiveNetworkInfo() != null) {
netSataus = cwjManager.getActiveNetworkInfo().isAvailable();
}
return netSataus;
}
}

  经过上面的代码虽然能够实现了图片的异步获取,自动缓存读取,图片压缩的功能,但是处理图片使图片适应控件大小还是比较让人头疼的问题,还有就是如果一起获取大量的网络的图片,会占用的非常多的内存,而且系统默认自由在界面销毁的时候才会释放,所以很容易遇到内存溢出的问题,下面向大家分享一个我在github上看到的一个处理网络的图片的程序。

能够实现异步获取图片,自动缓存读取,自动适应空间大小,而且完美解决内存溢出的问题

下面向大家展示一下:

以集街网(www.jijie.cc)中的一个图片为例,原图为:

<con.standopen.view.NetworkedCacheableImageView
android:id="@+id/nciv_pug"
android:layout_width="fill_parent"
android:layout_height="100dip"
android:scaleType="centerCrop" />

 <con.standopen.view.NetworkedCacheableImageView
android:id="@+id/nciv_pug"
android:layout_width="fill_parent"
android:layout_height="300dip"
android:scaleType="centerCrop" />

  <con.standopen.view.NetworkedCacheableImageView
android:id="@+id/nciv_pug"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop" />

  这分别是在不同大小的空间中显示同一张图片,能够看出来,代码只是将图片进行了剪切处理,避免拉伸变形,程序异步获取和自动缓存就不展示了,大家看代码就行的了。

工程文件(百度网盘):http://pan.baidu.com/s/1mguh2qc

github:https://github.com/yimengqingqiu/Android-Universal-Image-Loader

个人邮箱:standopen@foxmail.com(也可以发邮件给我索取)

分享一个安卓中异步获取网络图片并自适应大小的第三方程序(来自github)的更多相关文章

  1. php 从一个数组中随机获取固定数据

    <?php /* * * 通过一个标识,从一个数组中随机获取固定数据 * $arr 数组 * $num 获取的数量 * $time 随机固定标识值,一般用固定时间或者某个固定整型 * */ fu ...

  2. react+dva 全局model中异步获取数据state在组件中取不到值

    先上结论,不是取不到,是写法有问题. 全文分4部分,1是问题描述,2是一开始的解决想法(错误做法),3是问题产生原因的思考,4是正常解决方法.只想看结论直接跳4 1.问题描述 接触react dva一 ...

  3. 分享一个JDK批量异步任务工具CompletionService,超好用

    摘要:当需要批量提交异步任务,推荐CompletionService.CompletionService将线程池Executor和阻塞队列融合,让批量异步任务管理更简单. 本文分享自华为云社区< ...

  4. 使用SQL语句从数据库一个表中随机获取数据

    -- 随机获取 10 条数据 SQL Server:SELECT TOP 10 * FROM T_USER ORDER BY NEWID() ORACLE:SELECT * FROM (SELECT ...

  5. 分享一个工作中遇得到的sql(按每天每人统计拖车次数与小修次数)

    查询每人每天的数据 首先先建表 CREATE TABLE `user` ( `name` ) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CR ...

  6. 分享一个js中的bind方法使用

    来源:http://www.cnblogs.com/yuzhongwusan/archive/2012/02/13/2348782.html Js代码 复制代码 代码如下: var first_obj ...

  7. 分享一个vue中的vue-Resource用法

    //引入 <script src="//cdn.bootcss.com/vue-resource/1.2.1/vue-resource.js" type="text ...

  8. 分享一个linux中测试网站是否正常的shell脚本

    #! /bin/bash #Author=Harry CheckUrl() { #<==定义函数,名字为CheckUrl timeout=5 #<==定义wget访问的超时时间,超时就退出 ...

  9. 分享一个Python脚本--统计redis key类型数据大小分布

    概述 今天主要介绍怎么统计redis key类型数据大小分布. 原理:使用redis命令: scan.pipline.type 和 debug object 来得到 redis key 信息. 脚本 ...

随机推荐

  1. 你不需要jQuery(四)

    jQuery是个好东西.它诞生于IE6在互联网称霸的那个时代.jQuery的存在让我们的代码能很好的兼容各种平台. 然而,到如今,浏览器技术已经取得了巨大的进步.我们可以自由的使用所有最新众多ES5/ ...

  2. windows下游戏服务器端框架Firefly安装说明及demo运行

    原地址:http://blog.csdn.net/wangqiuyun/article/details/11150503 本来公司一个网游服务器端选定了pomelo框架,后来出了个Firefly,为做 ...

  3. how to make form:checkboxes in JSP

    retransmitTable.jsp file: <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix=&qu ...

  4. 深入理解c++中char*与wchar_t*与string以及wstring之间的相互转换

    本篇文章是对c++中的char*与wchar_t*与string以及wstring之间的相互转换进行了详细的分析介绍,需要的朋友参考下-复制代码 代码如下:    #ifndef USE_H_     ...

  5. Side-by-side assembly

    Side-by-side technology is a standard for executable files in Windows 98 Second Edition, Windows 200 ...

  6. 如何将DJANGO轻量级化

    看看这本书,应该有收获. 不用DJANGO-ADMIN STARTPROJECT XXX 一个文件,一样可以写出可以运行的原生DJANGO哟. import hashlib import sys im ...

  7. Hibernate逍遥游记-第2章-使用hibernate.properties

    1. package mypack; import org.hibernate.*; import org.hibernate.cfg.Configuration; import java.util. ...

  8. MYSQL 优化建议

    转自 http://coolshell.cn/articles/1846.html MYSQL 优化建议20条 1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效 ...

  9. profile工具

    gprof callgrind vtune(待使用) ----time命令(待学习) ps -u <username> -H -opid,cmd strace

  10. PHP微信公众平台开发1 配置接口

    1.简介 微信公众平台是腾讯公司在微信的基础上新增的功能模块,通过这一平台,个人和企业都可以打造一个微信的公众号,并实现和特定群体的文字.图片.语音的全方位沟通.互动. 2.通讯机制 3.注册微信公众 ...