什么贴图软件有close 和天天特价店铺活动和活动?

当前位置: →
声明:本站以非盈利为目的,所有软件和信息均免费。站内所有广告,如有收费行为,均与本站无任何关系!请广大网友小心谨慎。
Copyright &
. All Rights Reserved .页面执行时间:46.87500 毫秒网站备案信息:7×24 客服电话
香港:852-852-
台湾:886-2-
海外:86-10-
北京图际软件有限公司附近酒店
鸟巢/国家会议中心
前门/大栅栏
北京展览馆/首都体育馆
中关村/人民大学
北大/清华/学院路
首都机场、新国展
五棵松体育馆
北京站地区
东直门/簋街
北京南站/永定门
金融街/复兴门
工体/三里屯
航天桥/首都师范大学
鼓楼/后海/新街口
大钟寺/交通大学
东四/东四十条
朝阳门/秀水市场
六里桥长途汽车站
上地工业园区
朝阳公园/团结湖
朝阳北路/大悦城
欢乐谷/工业大学
潘家园/十里河
广安门/大观园
燕莎/农展馆
丽泽商务区
酒仙桥/798艺术园区
北苑/北京会议中心
石景山万达广场/鲁谷
亦庄经济技术开发区
房山城区、十渡风景区
大兴农业观光区
怀柔城区、雁栖湖风景区
密云城区、密云水库
平谷城区、金海湖风景区
延庆城区、八达岭长城
门头沟城区、妙峰山风景区
顺义温泉度假区
昌平城区、小汤山温泉度假区
南宫温泉度假区
南苑机场、南宫地区
港中旅维景
更多品牌酒店
免费停车场
精品酒店(设计师酒店)
0家酒店满足条件
只看返后价
当前促销:
预付更优惠
距离北京图际软件有限公司的直线距离约98米
服务指数:3.6/5分
距离北京图际软件有限公司的直线距离约0.1公里
来自100条点评
服务指数:4.7/5分
距离北京图际软件有限公司的直线距离约0.3公里
来自2条点评
服务指数:4.4/5分
距离北京图际软件有限公司的直线距离约0.3公里
来自7条点评
服务指数:3.6/5分
距离北京图际软件有限公司的直线距离约0.3公里
来自897条点评
服务指数:3.6/5分
距离北京图际软件有限公司的直线距离约0.4公里
来自54条点评
服务指数:4.2/5分
大/大/双床
距离北京图际软件有限公司的直线距离约0.5公里
来自181条点评
服务指数:4.7/5分
距离北京图际软件有限公司的直线距离约0.5公里
来自175条点评
服务指数:4.4/5分
距离北京图际软件有限公司的直线距离约0.6公里
来自90条点评
服务指数:4.1/5分
距离北京图际软件有限公司的直线距离约0.6公里
来自3条点评
服务指数:4.1/5分
北京酒店信息
【北京图际软件有限公司附近酒店】点评
"还可以。地段比较方便"
"如家一如既往的好,服务也很不错"
"很不错的客栈,物超所值,去丽江古城可以考虑"
"环境好,服务好!下次再来!"
"环境不错,就是特价房入住的时候有点小波折,艺龙客服帮忙解决了"
"很棒的~干净 态度好~环境也好~~"
"房间还不错,就是押金收得有点太多了,出门在外没那么多现金很不方便"
"希望大家都来这个酒店,这里住的非常舒服,"
"很好,交通方便下次在来,"
"前台服务还可以,电视可选台太少。。。。"
北京图际软件有限公司简介
从"北京图际软件有限公司"步行403米到海淀区中关村大街27号中关村大厦(近海淀医院)的中国建设银行中关村支行;或步行178米到海淀区中关村大街甲28号(近慈铭体检知春分部)的北京银行中关村科技园区支行;或步行203米到海淀区知春路113号银网中心内的中国民生银行中关村支行.附近值得一去的景点有北京市海淀区博物馆,位于海淀区中关村大街28-1号(近海淀剧院广场),直线距离174米.双榆树公园,位于海淀区科学院南路31号,直线距离694米.知春公园,位于知春东里五小区南,直线距离576米."北京图际软件有限公司"附近的公交站有海淀黄庄东站,您可乘坐304路,386路,611路到达.海淀黄庄南站,您可乘坐302路,320路,320区到达.海淀黄庄西站,您可乘坐304路,386路,611路到达.海淀黄庄北站,您可乘坐85路,307路,320路到达.从"北京图际软件有限公司"出发,周围585米范围内,在科学院南路知春东里13号楼(384、323慢车知春里车站往南60米路东)有一家戈拿旺巴西烤肉(海淀店),订餐电话(010).周围339米范围内,在北京市海淀区海淀南路(海淀医院斜对面)有一家九头鹰酒家知春路店,订餐电话(010).周围375米范围内,在北京市海淀区中关村大街27号中关村大厦二层有一家眉州东坡酒楼(中关村店),订餐电话(010).
新人首订礼
新用户福利来啦!首次下单可享受“新人首订礼“,在您成功入住结账后5-7个工作日,小艺会给您账户额外赠送订单金额10%的礼品卡!最高可返200元哦!
即日起至日,每位艺龙个人会员通过艺龙官方网站(www.
)及无线客户端成功预订标有“会员奖励”字样的酒店房间且如约实际入住的,每达到5个间夜即可获赠与该5间夜房间平均价格相等金额的艺龙酒店礼品卡。
获赠礼品卡将在每月10日前充值到本人艺龙账户,礼品卡有效期1年,活动可累加,多住多送。
欢迎加入小艺 QQ群: 和我们直接沟通
如果您对我们的产品有什么建议和问题,请告诉我们:)
如有紧急订单问题,请拨打艺龙24小时服务热线:
谢谢您的反馈
如果您填写了邮箱,我们会邮件联系您哦~
谢谢您的反馈
但系统可能有些烦忙,请您稍后尝试哦~
清空对比栏
大家都住哪儿
手机预订 5万家超低折扣酒店
方法:扫描二维码下载
方法:输入手机号下载
请输入正确的手机号3628人阅读
&&&&&&转载请标明出处:
&&&&&&&这篇是基于上一篇来进行讲解,没看过的可以先阅读下上一篇博文,其实我个人觉得图片双缓存处理这块,一张流程图已足以说明一切。至于编码实现,不同的人有不同的实现方式,下面我就和大家聊一聊我的实现方式:
一、图片双缓存处理,类图如下:
二、网络图片本地双缓存的编码实现(以获取用户图像为例):
&&&&& &1、发出需要显示用户图像的请求
String headUrl = user.getHeadurl();
LogUtil.i(TAG, &headUrl = & + user.getHeadurl());
// 用户图像的大小48x48,单位为dip,转换为px
int widthPx = DensityUtil.dip2px(mContext, 48);
// 要一张圆角高质量的图片
ImageInfo imgInfo = new ImageInfo(mLeftPanelLayout.ivUserIcon, headUrl, widthPx, widthPx, true, false);
mImageLoader.displayImage(imgInfo);
&&&&&&&&注:mLeftPanelLayout.ivUserIcon为ImageView;ImageInfo对象封装了图片请求参数。
&&&&&&&&2、根据URL从内存缓存中获取Bitmap对象,找到了Bitmap对象,用ImageView对象显示图像,到这里终止。
Bitmap bitmap = memoryCache.get(url);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
&&&&&&&&&&&注:memoryCache是MemoryCache(内存缓存类)的对象引用。
&&&&&&&&3 、没有从缓存中找到了Bitmap对象,则根据URL从文件缓存中获取File对象,将File对象解码(解析)成Bitmap对象,用ImageView对象显示用户图像,到这里终止。
final File file = fileCache.getFile(url);
if(file.exists()){
String pathName = file.getAbsolutePath();
System.out.println(&pathName = & + pathName);
System.out.println(&file.length() = & + file.length());
bitmap = BitmapFactory.decodeFile(pathName);
imageView.setImageBitmap(bitmap);
&&&&&&&&&& 注:fileCache为文件缓存类的引用&&&&&&&&&&&&&
&&&&&&&&4、没有从文件缓存中找到File对象,则开启网络请求业务线程。
// 开启线程加载图片
AsyncBaseRequest asyncRequest = new AsyncHttpGet(url, null, null, new ResultCallback() {
public void onSuccess(Object obj) {
public void onFail(int errorCode) {
System.out.println(&Loading image error. errorCode = & + errorCode);
mDefaultThreadPool.execute(asyncRequest);
mAsyncRequests.add(asyncRequest);
} catch (IOException e) {
e.printStackTrace();
&&&&&&& &5、网络请求返回的图片数据流可能会很大,直接解码生成Bitmap对象,可能会造成OOM。因此,要根据指定的压缩比例,获得合适的Bitmap
Bitmap bitmap = BitmapUtil.decodeStream((InputStream) obj, imgInfo.getWidth(), imgInfo.getHeight());
&&&&&&&&6、上一步处理过后,可能解码生成的Bitmap对象还会很大,可能还会造成OOM,因此,对Bitmap对象再次进行质量压缩。
if (imgInfo.isCompress()) {
// 对Bitmap进行质量压缩
bitmap = pressBitmap(bitmap);
&&&&&&7、进行本地文件缓存
fileCache.writeToFile(inStream, file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
&&&&&&8、进行本地内存缓存
// 将数据流将其转换成Bitmap
bitmap = BitmapFactory.decodeStream(inStream);
// 存入内存缓存中
memoryCache.put(url, bitmap);
&&&&&&9、用ImageView对象显示用户图像,到这里终止。
// 用ImageView对象显示图片
final Bitmap btm =
mHandler.post(new Runnable() {
public void run() {
imageView.setImageBitmap(btm);
&&&&&& 加载图片的完整方法,代码如下:
* 加载图片
* @param imgInfo 图片信息
public void displayImage(final ImageInfo imgInfo) {
final ImageView imageView = imgInfo.getImageView();
final String url = imgInfo.getUrl();
imageViews.put(imageView, url);
// 从内存缓存中查找
Bitmap bitmap = memoryCache.get(url);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
// 从文件缓存中查找
final File file = fileCache.getFile(url);
if (file.exists()) {
String pathName = file.getAbsolutePath();
System.out.println(&pathName = & + pathName);
System.out.println(&file.length() = & + file.length());
bitmap = BitmapFactory.decodeFile(pathName);
imageView.setImageBitmap(bitmap);
// 开启线程加载图片
AsyncBaseRequest asyncRequest = new AsyncHttpGet(url, null, null, new ResultCallback() {
public void onSuccess(Object obj) {
if (obj == null || !(obj instanceof InputStream)) {
System.out.println(&Loading image return Object is null or not is InputStream.&);
// 根据指定的压缩比例,获得合适的Bitmap
Bitmap bitmap = BitmapUtil.decodeStream((InputStream) obj, imgInfo.getWidth(), imgInfo.getHeight());
if (imgInfo.isRounded()) {
// 将图片变成圆角
// bitmap = BitmapUtil.drawRoundCorner(bitmap, 8);
bitmap = BitmapUtil.drawRoundBitmap(bitmap, 8);
if (imgInfo.isCompress()) {
// 对Bitmap进行质量压缩
bitmap = pressBitmap(bitmap);
// 将Bitmap转换成ByteArrayInputStream
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
pressFormat.PNG, 100, outStream);
ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
// 将进行质量压缩后的数据写入文件(文件缓存)
fileCache.writeToFile(inStream, file);
// 存入内存缓存中
memoryCache.put(url, bitmap);
// 防止图片错位
String tag = imageViews.get(imageView);
if (tag == null || !tag.equals(url)) {
System.out.println(&tag is null or url and ImageView disaccord.&);
// 用ImageView对象显示图片
final Bitmap btm =
mHandler.post(new Runnable() {
public void run() {
imageView.setImageBitmap(btm);
} catch (IOException e) {
// 这里不做处理,因为默认显示的图片在xml组件配置里已设置
e.printStackTrace();
public void onFail(int errorCode) {
System.out.println(&Loading image error. errorCode = & + errorCode);
mDefaultThreadPool.execute(asyncRequest);
mAsyncRequests.add(asyncRequest);
} catch (IOException e) {
e.printStackTrace();
&&&&& 三、在上述业务处理过程中,遇到的问题及解决思路(记录处理过程)
&&&&&&&1、根据指定的压缩比例,获得合适的Bitmap,阅读如下代码:
* 根据指定的压缩比例,获得合适的Bitmap
* @param inStream InputStream
* @param width 指定的宽度
* @param height 指定的高度
public static Bitmap decodeStream(InputStream inStream, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds =
BitmapFactory.decodeStream(inStream, null, options);
int w = options.outW
int h = options.outH
// 从服务器端获取的图片大小为:80x120
// 我们想要的图片大小为:40x40
// 缩放比:120/40 = 3,也就是说我们要的图片大小为原图的1/3
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int ratio = 1; // 默认为不缩放
if (w &= h && w & width) {
ratio = (int) (w / width);
} else if (w & h && h & height) {
ratio = (int) (h / height);
if (ratio &= 0) {
ratio = 1;
System.out.println(&图片的缩放比例值ratio = & + ratio);
options.inJustDecodeBounds =
// 属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,
// 则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。
options.inSampleSize =
return BitmapFactory.decodeStream(inStream, null, options);
&&&&&& 注:inStream为从网络获取后,直接传进来的。
&&&&&&&运行上面的后,返回的Bitmap对象为null。究其原因,在设置&options.inJustDecodeBounds = true后,我们调用了BitmapFactory.decodeStream(inStream, null, options)方法获取图片的大小,但是该方法在执行完后,应该在内部把传进去的InputStream关闭掉了。第二次的时候就读不到数据了。解决思路,将从网络获取到的数据流先保存起来。解决方法一:
* 根据指定的压缩比例,获得合适的Bitmap(方法一)
* @param file File
* @param width 指定的宽度
* @param height 指定的高度
* @return Bitmap
public static Bitmap decodeStream(File file, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds =
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
int w = options.outW
int h = options.outH
// 从服务器端获取的图片大小为:80x120
// 我们想要的图片大小为:40x40
// 缩放比:120/40 = 3,也就是说我们要的图片大小为原图的1/3
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int ratio = 1; // 默认为不缩放
if (w &= h && w & width) {
ratio = (int) (w / width);
} else if (w & h && h & height) {
ratio = (int) (h / height);
if (ratio &= 0) {
ratio = 1;
System.out.println(&图片的缩放比例值ratio = & + ratio);
options = new BitmapFactory.Options();
options.inJustDecodeBounds =
// 属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,
// 则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。
options.inSampleSize =
return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
解决方法二:
* 根据指定的压缩比例,获得合适的Bitmap(方法二)
* @param inStream InputStream
* @param width 指定的宽度
* @param height 指定的高度
* @return Bitmap
* @throws IOException
public static Bitmap decodeStream(InputStream inStream, int width, int height) throws IOException {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds =
// 从输入流读取数据
byte[] data = StreamTool.read(inStream);
BitmapFactory.decodeByteArray(data, 0, data.length, options);
int w = options.outW
int h = options.outH
// 从服务器端获取的图片大小为:80x120
// 我们想要的图片大小为:40x40
// 缩放比:120/40 = 3,也就是说我们要的图片大小为原图的1/3
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int ratio = 1; // 默认为不缩放
if (w &= h && w & width) {
ratio = (int) (w / width);
} else if (w & h && h & height) {
ratio = (int) (h / height);
if (ratio &= 0) {
ratio = 1;
System.out.println(&图片的缩放比例值ratio = & + ratio);
options.inJustDecodeBounds =
// 属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,
// 则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。
options.inSampleSize =
return BitmapFactory.decodeByteArray(data, 0, data.length);
解决方法三:从网络返回的数据流中只读取图片的信息(宽度和高度),计算压缩比例,之后再次从网络读取数据按第一次计算出的压缩比例,获得合适的Bitmap。(这个是下下策,要访问两次网络)
&&&&&& 2、对Bitmap进行质量压缩,阅读如下代码:
* 对Bitmap进行质量压缩
* @param bitmap Bitmap
* @return ByteArrayInputStream
public static Bitmap compressBitmap(Bitmap bitmap) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// 图片质量默认值为100,表示不压缩
int quality = 100;
// PNG是无损的,将会忽略质量设置。因此,这里设置为JPEG
pressFormat.JPEG, quality, outStream);
// 判断压缩后图片的大小是否大于100KB,大于则继续压缩
while (outStream.toByteArray().length / 1024 & 100) {
outStream.reset();
// 压缩quality%,把压缩后的数据存放到baos中
pressFormat.JPEG, quality, outStream);
quality -= 10;
System.out.println(&quality = & + quality);
byte[] data = outStream.toByteArray();
return BitmapFactory.decodeByteArray(data, 0, data.length);
&&&&&&&&注意:& pressFormat.PNG, quality, outStream);如果这么写,是没有压缩效果的。因为PNG是无损的,将会忽略质量设置。
四、上述讲解中涉及到的类,完整的源文件如下:
加载(装载)图片类
package com.everyone.android.
import java.io.ByteArrayInputS
import java.io.ByteArrayOutputS
import java.io.F
import java.io.IOE
import java.io.InputS
import java.text.SimpleDateF
import java.util.C
import java.util.LinkedHashM
import java.util.L
import java.util.M
import android.graphics.B
import android.graphics.BitmapF
import android.os.H
import android.widget.ImageV
import com.everyone.android.AppBaseA
import com.everyone.android.callback.ResultC
import com.everyone.android.entity.ImageI
import com.everyone.android.net.AsyncBaseR
import com.everyone.android.net.AsyncHttpG
import com.everyone.android.net.DefaultThreadP
import com.everyone.android.utils.BitmapU
* 功能描述:加载(装载)图片
* 在以前,一个非常流行的内存缓存的实现是使用SoftReference or WeakReference ,但是这种办法现在并不推荐。
* 从Android 2.3开始,垃圾回收器会更加积极的去回收软引用和弱引用引用的对象,这样导致这种做法相当的无效。
* 另外,在Android 3.0之前,图片数据保存在本地内存中,它们不是以一种可预见的方式来释放的,
* 这样可能会导致应用内存的消耗量出现短暂的超限,应用程序崩溃 。
* @author android_ls
public class ImageLoader {
* 内存缓存
private MemoryCache memoryC
* 文件缓存
private FileCache fileC
* 存放图片的显示视图ImageView和图片的URL
private Map&ImageView, String& imageViews = Collections.synchronizedMap(new LinkedHashMap&ImageView, String&());
private List&AsyncBaseRequest& mAsyncR
private DefaultThreadPool mDefaultThreadP
private Handler mH
public ImageLoader(AppBaseActivity activity) {
this.memoryCache = new MemoryCache();
this.fileCache = new FileCache(activity.getContext());
this.mAsyncRequests = activity.getAsyncRequests();
this.mDefaultThreadPool = activity.getDefaultThreadPool();
this.mHandler = activity.getHandler();
* 加载图片
* @param imgInfo 图片信息
public void displayImage(final ImageInfo imgInfo) {
final ImageView imageView = imgInfo.getImageView();
final String url = imgInfo.getUrl();
imageViews.put(imageView, url);
// 从内存缓存中查找
Bitmap bitmap = memoryCache.get(url);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
// 从文件缓存中查找
final File file = fileCache.getFile(url);
if (file.exists()) {
String pathName = file.getAbsolutePath();
System.out.println(&pathName = & + pathName);
System.out.println(&file.length() = & + file.length());
SimpleDateFormat mDateFormat = new SimpleDateFormat (&yyyy年MM月dd日 HH:mm:ss&);
System.out.println(&file.lastModified() = & + mDateFormat.format(file.lastModified()));
bitmap = BitmapFactory.decodeFile(pathName);
imageView.setImageBitmap(bitmap);
// 开启线程加载图片
AsyncBaseRequest asyncRequest = new AsyncHttpGet(url, null, null, new ResultCallback() {
public void onSuccess(Object obj) {
if (obj == null || !(obj instanceof InputStream)) {
System.out.println(&Loading image return Object is null or not is InputStream.&);
// 根据指定的压缩比例,获得合适的Bitmap
Bitmap bitmap = BitmapUtil.decodeStream((InputStream) obj, imgInfo.getWidth(), imgInfo.getHeight());
if (imgInfo.isRounded()) {
// 将图片变成圆角
// bitmap = BitmapUtil.drawRoundCorner(bitmap, 8);
bitmap = BitmapUtil.drawRoundBitmap(bitmap, 8);
if (imgInfo.isCompress()) {
// 对Bitmap进行质量压缩
bitmap = pressBitmap(bitmap);
// 将Bitmap转换成ByteArrayInputStream
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
pressFormat.PNG, 100, outStream);
ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
// 将进行质量压缩后的数据写入文件(文件缓存)
fileCache.writeToFile(inStream, file);
// 存入内存缓存中
memoryCache.put(url, bitmap);
// 防止图片错位
String tag = imageViews.get(imageView);
if (tag == null || !tag.equals(url)) {
System.out.println(&tag is null or url and ImageView disaccord.&);
// 用ImageView对象显示图片
final Bitmap btm =
mHandler.post(new Runnable() {
public void run() {
imageView.setImageBitmap(btm);
} catch (IOException e) {
// 这里不做处理,因为默认显示的图片在xml组件配置里已设置
e.printStackTrace();
public void onFail(int errorCode) {
System.out.println(&Loading image error. errorCode = & + errorCode);
mDefaultThreadPool.execute(asyncRequest);
mAsyncRequests.add(asyncRequest);
} catch (IOException e) {
e.printStackTrace();
内存缓存类
package com.everyone.android.
import java.util.C
import java.util.I
import java.util.LinkedHashM
import java.util.M
import java.util.Map.E
import android.graphics.B
import android.util.L
* 功能描述:内存缓存类
* @author android_ls
public class MemoryCache {
* 打印LOG的TAG
private static final String TAG = &MemoryCache&;
* 放入缓存时是个同步操作
* LinkedHashMap构造方法的最后一个参数true代表这个map里的元素将按照最近使用次数由少到多排列,
* 这样的好处是如果要将缓存中的元素替换,则先遍历出最近最少使用的元素来替换以提高效率
private Map&String, Bitmap& cacheMap = Collections.synchronizedMap(new LinkedHashMap&String, Bitmap&(10, 1.5f, true));
// 缓存只能占用的最大堆内存
private long maxM
public MemoryCache() {
// 使用25%的可用的堆大小
maxMemory = Runtime.getRuntime().maxMemory() / 4;
Log.i(TAG, &MemoryCache will use up to & + (maxMemory / 1024 / 1024) + &MB&);
* 根据key获取相应的图片
* @param key
* @return Bitmap
public Bitmap get(String key) {
if (!cacheMap.containsKey(key)){
return cacheMap.get(key);
* 添加图片到缓存
* @param key
* @param bitmap
public synchronized void put(String key, Bitmap bitmap) {
checkSize();
cacheMap.put(key, bitmap);
Log.i(TAG, &cache size=& + cacheMap.size() + & bitmap size = & +
getBitmapSize(bitmap));
* 严格控制堆内存,如果超过将首先替换最近最少使用的那个图片缓存
private void checkSize() {
long count = 0;
Iterator&Entry&String, Bitmap&& iterator = cacheMap.entrySet().iterator();
while (iterator.hasNext()) {
Entry&String, Bitmap& entry = iterator.next();
count += getBitmapSize(entry.getValue());
Log.i(TAG, &cache size=& + count + & length=& + cacheMap.size());
if (count & maxMemory) {
while (iterator.hasNext()) {
Entry&String, Bitmap& entry = iterator.next();
count -= getBitmapSize(entry.getValue());
iterator.remove();
if (count &= maxMemory) {
System.out.println(&够用了,不用在删除了&);
Log.i(TAG, &Clean cache. New size & + cacheMap.size());
* 获取bitmap的字节大小
* @param bitmap
private long getBitmapSize(Bitmap bitmap) {
if (bitmap == null) {
return bitmap.getRowBytes() * bitmap.getHeight();
* 清空缓存
public void clear() {
cacheMap.clear();
网络下载文件本地缓存类
package com.everyone.android.
import java.io.F
import java.io.FileOutputS
import java.io.IOE
import java.io.InputS
import java.text.SimpleDateF
import java.util.A
import android.content.C
import android.os.StatFs;
* 功能描述:网络下载文件本地缓存类
* @author android_ls
public class FileCache {
* 本地与我们应用程序相关文件存放的根目录
private static final String ROOT_DIR_PATH = &CopyEveryone&;
* 下载文件存放的目录
private static final String IMAGE_DOWNLOAD_CACHE_PATH = ROOT_DIR_PATH + &/Download/cache&;
* 默认的磁盘缓存大小(20MB)
private static final int DEFAULT_DISK_CACHE_SIZE = 1024 * 1024 * 20;
* 缓存文件存放目录
private File cacheD
* 缓存根目录
private String cacheRootD
private Context mC
public FileCache(Context context) {
mContext =
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
cacheRootDir = android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
cacheRootDir = mContext.getCacheDir().getAbsolutePath();
cacheDir = new File(cacheRootDir + File.separator + IMAGE_DOWNLOAD_CACHE_PATH);
// 检测文件缓存目录是否存在,不存在则创建
if (!cacheDir.exists()) {
cacheDir.mkdirs();
* 获取下载的文件要存放的缓存目录
* /mnt/sdcard/CopyEveryone/Download/cache
* @return 缓存目录的全路径
public String getCacheDirPath() {
return cacheDir.getAbsolutePath();
* 根据URL从文件缓存中获取文件
* @param url url的hashCode为缓存的文件名
public File getFile(String url) {
if (!cacheDir.exists()) {
cacheDir.mkdirs();
String filename = String.valueOf(url.hashCode());
File file = new File(cacheDir, filename);
* 计算存储可用的大小
public long getAvailableMemorySize() {
StatFs stat = new StatFs(cacheRootDir);
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockS
* 将指定的数据写入文件
* @param inputStream InputStream
* @param outputStream OutputStream
* @throws IOException
public synchronized void writeToFile(InputStream inputStream, File file) throws IOException {
int fileSize
= inputStream.available();
System.out.println(&fileSize = & + fileSize);
long enabledMemory
= getAvailableMemorySize();
System.out.println(&当前可用硬盘: & + (enabledMemory/)); // 单位:MB
// 当前可用存储空间不足20M
if(DEFAULT_DISK_CACHE_SIZE & enabledMemory){
if (fileSize & enabledMemory) {
// 检测可用空间大小,若不够用则删除最早的文件
File[] files = cacheDir.listFiles();
Arrays.sort(files, new FileLastModifSort());
int length = files.
for (int i = 0; i & i++) {
files[i].delete();
length = files.
enabledMemory
= getAvailableMemorySize();
System.out.println(&当前可用内存: & + enabledMemory);
if (fileSize &= enabledMemory) {
System.out.println(&够用了,不用在删除了&);
int count = 0;
File[] files = cacheDir.listFiles();
for (int i = 0; i & files. i++) {
count += files[i].length();
System.out.println(&file cache size = & + count);
// 使用的空间大于上限
enabledMemory = DEFAULT_DISK_CACHE_SIZE -
if(fileSize & enabledMemory){
Arrays.sort(files, new FileLastModifSort());
int length = files.
for (int i = 0; i & i++) {
count -= files[i].length();
files[i].delete();
length = files.
enabledMemory = DEFAULT_DISK_CACHE_SIZE -
if (fileSize &= enabledMemory) {
System.out.println(&够用了,不用在删除了&);
if(enabledMemory == 0){
// 将数据写入文件保存
FileOutputStream outStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
outStream.flush();
outStream.close();
inputStream.close();
// 设置最后修改的时间
long newModifiedTime = System.currentTimeMillis();
file.setLastModified(newModifiedTime);
System.out.println(&file.length() = & + file.length());
SimpleDateFormat mDateFormat = new SimpleDateFormat (&yyyy年MM月dd日 HH:mm:ss&);
System.out.println(&writeToFile file.lastModified() = & + mDateFormat.format(file.lastModified()));
* 根据文件的最后修改时间进行排序
* @author android_ls
class FileLastModifSort implements Comparator&File& {
public int compare(File file1, File file2) {
if (file1.lastModified() & file2.lastModified()) {
} else if (file1.lastModified() == file2.lastModified()) {
return -1;
* 清空缓存的文件
public void clear() {
if (!cacheDir.exists()) {
File[] files = cacheDir.listFiles();
if (files != null) {
for (File f : files) {
f.delete();
图片信息实体类
package com.everyone.android.
import android.widget.ImageV
* 功能描述:图片信息实体类
* @author android_ls
public class ImageInfo {
// 唯一标识
private ImageView imageV // 用于显示的组件
private S // 网络URL
pri // 是否要转换成圆角
priv // 是否要进行质量压缩
public ImageInfo(ImageView imageView, String url) {
this.imageView = imageV
this.url =
public ImageInfo() {
public ImageInfo(ImageView imageView, String url, int width, int height, boolean rounded, boolean compress) {
this.imageView = imageV
this.url =
this.width =
this.height =
this.rounded =
public ImageInfo(ImageView imageView, String url, boolean rounded) {
this.imageView = imageV
this.url =
this.rounded =
public ImageInfo(ImageView imageView, String url, int width, int height) {
this.imageView = imageV
this.url =
this.width =
this.height =
public ImageInfo(ImageView imageView, String url, int width, int height, boolean rounded) {
this.imageView = imageV
this.url =
this.width =
this.height =
this.rounded =
public boolean isCompress() {
public void setCompress(boolean compress) {
public int getId() {
public void setId(int id) {
public ImageView getImageView() {
return imageV
public void setImageView(ImageView imageView) {
this.imageView = imageV
public String getUrl() {
public void setUrl(String url) {
this.url =
public int getWidth() {
public void setWidth(int width) {
this.width =
public int getHeight() {
public void setHeight(int height) {
this.height =
public boolean isRounded() {
public void setRounded(boolean rounded) {
this.rounded =
Bitmap加工处理工具类
package com.everyone.android.
import java.io.ByteArrayOutputS
import java.io.F
import java.io.IOE
import java.io.InputS
import android.graphics.B
import android.graphics.Bitmap.C
import android.graphics.BitmapF
import android.graphics.C
import android.graphics.C
import android.graphics.P
import android.graphics.PorterD
import android.graphics.PorterDuff.M
import android.graphics.PorterDuffX
import android.graphics.R
import android.graphics.RectF;
import android.graphics.drawable.BitmapD
import android.graphics.drawable.D
* 功能描述:Bitmap加工处理工具类
* @author android_ls
public class BitmapUtil {
* 将图片变成圆角(方法一)
* @param bitmap Bitmap
* @param pixels 圆角的弧度
* @return 圆角图片
public static Bitmap drawRoundBitmap(Bitmap bitmap, float pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
// paint.setColor()的参数,除不能为Color.TRANSPARENT外,可以任意写
paint.setColor(Color.RED);
canvas.drawRoundRect(rectF, pixels, pixels, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
* 将图片变成圆角(方法二)
* @param bitmap Bitmap
* @param pixels 圆角的弧度
* @return 圆角图片
public static Bitmap drawRoundCorner(Bitmap bitmap, float pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
RectF outerRect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// paint.setColor()的参数,除不能为Color.TRANSPARENT外,可以任意写
paint.setColor(Color.WHITE);
canvas.drawRoundRect(outerRect, pixels, pixels, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
Drawable drawable = new BitmapDrawable(bitmap);
drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.saveLayer(outerRect, paint, Canvas.ALL_SAVE_FLAG);
drawable.draw(canvas);
canvas.restore();
* 对Bitmap进行质量压缩
* @param bitmap Bitmap
* @return ByteArrayInputStream
public static Bitmap compressBitmap(Bitmap bitmap) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// 图片质量默认值为100,表示不压缩
int quality = 100;
// PNG是无损的,将会忽略质量设置。因此,这里设置为JPEG
pressFormat.JPEG, quality, outStream);
// 判断压缩后图片的大小是否大于100KB,大于则继续压缩
while (outStream.toByteArray().length / 1024 & 100) {
outStream.reset();
// 压缩quality%,把压缩后的数据存放到baos中
pressFormat.JPEG, quality, outStream);
quality -= 10;
System.out.println(&quality = & + quality);
byte[] data = outStream.toByteArray();
return BitmapFactory.decodeByteArray(data, 0, data.length);
* 根据指定的压缩比例,获得合适的Bitmap(方法一)
* @param file File
* @param width 指定的宽度
* @param height 指定的高度
* @return Bitmap
public static Bitmap decodeStream(File file, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds =
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
int w = options.outW
int h = options.outH
// 从服务器端获取的图片大小为:80x120
// 我们想要的图片大小为:40x40
// 缩放比:120/40 = 3,也就是说我们要的图片大小为原图的1/3
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int ratio = 1; // 默认为不缩放
if (w &= h && w & width) {
ratio = (int) (w / width);
} else if (w & h && h & height) {
ratio = (int) (h / height);
if (ratio &= 0) {
ratio = 1;
System.out.println(&图片的缩放比例值ratio = & + ratio);
options = new BitmapFactory.Options();
options.inJustDecodeBounds =
// 属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,
// 则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。
options.inSampleSize =
return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
* 根据指定的压缩比例,获得合适的Bitmap(方法二)
* @param inStream InputStream
* @param width 指定的宽度
* @param height 指定的高度
* @return Bitmap
* @throws IOException
public static Bitmap decodeStream(InputStream inStream, int width, int height) throws IOException {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds =
// 从输入流读取数据
byte[] data = StreamTool.read(inStream);
BitmapFactory.decodeByteArray(data, 0, data.length, options);
int w = options.outW
int h = options.outH
// 从服务器端获取的图片大小为:80x120
// 我们想要的图片大小为:40x40
// 缩放比:120/40 = 3,也就是说我们要的图片大小为原图的1/3
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int ratio = 1; // 默认为不缩放
if (w &= h && w & width) {
ratio = (int) (w / width);
} else if (w & h && h & height) {
ratio = (int) (h / height);
if (ratio &= 0) {
ratio = 1;
System.out.println(&图片的缩放比例值ratio = & + ratio);
options.inJustDecodeBounds =
// 属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,
// 则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。
options.inSampleSize =
return BitmapFactory.decodeByteArray(data, 0, data.length);
* 根据指定的压缩比例,获得合适的Bitmap(会出错的方法,仅用于测试)
* @param inStream
* @param width
* @param height
* @throws IOException
public static Bitmap decodeStreamError(InputStream inStream, int width, int height) throws IOException {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds =
BitmapFactory.decodeStream(inStream, null, options);
int w = options.outW
int h = options.outH
// 从服务器端获取的图片大小为:80x120
// 我们想要的图片大小为:40x40
// 缩放比:120/40 = 3,也就是说我们要的图片大小为原图的1/3
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int ratio = 1; // 默认为不缩放
if (w &= h && w & width) {
ratio = (int) (w / width);
} else if (w & h && h & height) {
ratio = (int) (h / height);
if (ratio &= 0) {
ratio = 1;
System.out.println(&图片的缩放比例值ratio = & + ratio);
options.inJustDecodeBounds =
// 属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,
// 则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。
options.inSampleSize =
return BitmapFactory.decodeStream(inStream, null, options);
单位转换工具类
package com.everyone.android.
import android.content.C
* 功能描述:单位转换工具类
* @author android_ls
public class DensityUtil {
* 将单位为dip的值转换成单位为px的值
* @param context Context
* @param dipValue dip值
* @return px值
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().
return (int) (dipValue * scale + 0.5f);
* 将单位为px的值转换成单位为dip的值
* @param context Context
* @param pxValue 像素值
* @return dip值
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().
return (int) (pxValue / scale + 0.5f);
* 将px值转换为sp值,保证文字大小不变
* @param pxValue
* @param fontScale(DisplayMetrics类中属性scaledDensity)
public static int px2sp(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().
return (int) (pxValue / scale + 0.5f);
* 将sp值转换为px值,保证文字大小不变
* @param spValue
* @param fontScale(DisplayMetrics类中属性scaledDensity)
public static int sp2px(Context context, float spValue) {
final float scale = context.getResources().getDisplayMetrics().
return (int) (spValue * scale + 0.5f);
数据流处理工具类数据流处理工具类数据流处理工具类
package com.everyone.android.
import java.io.ByteArrayOutputS
import java.io.IOE
import java.io.InputS
* 功能描述:数据流处理工具类
* @author android_ls
public final class StreamTool {
* 从输入流读取数据
* @param inStream
* @throws IOException
* @throws Exception
public static byte[] read(InputStream inStream) throws IOException {
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
outSteam.close();
inStream.close();
return outSteam.toByteArray();
五、网络模块修改的文件源码:
&&&&& 网络请求线程基类
package com.everyone.android.
import java.io.IOE
import java.io.InputS
import java.io.S
import java.net.HttpURLC
import java.util.M
import org.json.JSONE
import com.everyone.android.callback.ParseC
import com.everyone.android.callback.ResultC
import com.everyone.android.utils.C
import com.everyone.android.utils.LogU
import com.everyone.android.utils.StreamT
* 功能描述:网络请求线程基类
* @author android_ls
public abstract class AsyncBaseRequest implements Runnable, Serializable {
private static final long serialVersionUID = 1L;
* LOG打印标签
private static final String TAG = &AsyncBaseRequest&;
* 网络连接超时,默认值为5秒
protected int connectTimeout = 5 * 1000;
* 网络数据读取超时,默认值为5秒
protected int readTimeout = 5 * 1000;
public boolean isInterrupted() {
public void setInterrupted(boolean interrupted) {
this.interrupted =
protected void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectT
protected void setReadTimeout(int readTimeout) {
this.readTimeout = readT
protected String requestU
protected Map&String, String&
private ParseCallback parseH
private ResultCallback requestC
protected HttpURLConnection mHttpURLC
protected InputStream mInS
public AsyncBaseRequest(String url, Map&String, String& parameter, ParseCallback handler, ResultCallback requestCallback) {
this.parseHandler =
this.requestUrl =
this.parameter =
this.requestCallback = requestC
* 发送网络请求
* @return 网络请求返回的InputStream数据流
* @throws IOException
protected abstract InputStream getRequestResult() throws IOE
public void run() {
if (interrupted) {
LogUtil.i(TAG, &访问网络前中断业务处理线程(终止)&);
mInStream = getRequestResult();
if (mInStream != null) {
if (interrupted) {
LogUtil.i(TAG, &读取数据前中断业务处理线程(终止)&);
Object obj =
if(parseHandler != null){
byte[] data = StreamTool.read(mInStream);
if (interrupted) {
LogUtil.i(TAG, &解析数据前中断业务处理线程(终止)&);
String result = new String(data);
obj = parseHandler.parse(result);
if (interrupted) {
LogUtil.i(TAG, &刷新UI前中断业务处理线程(终止)&);
if(obj != null){
requestCallback.onSuccess(obj);
requestCallback.onSuccess(mInStream);
LogUtil.i(TAG, &get InputStream By HttpURLConnection return result is NULL.&);
requestCallback.onFail(Constant.NETWORK_REQUEST_RETUN_NULL); // 网络请求返回NULL
} catch (JSONException e) {
requestCallback.onFail(Constant.NETWORK_REQUEST_RESULT_PARSE_ERROR); // 网络请求返回结果解析出错
e.printStackTrace();
} catch (IOException e) {
requestCallback.onFail(Constant.NETWORK_REQUEST_IOEXCEPTION_CODE); // IO异常标识
e.printStackTrace();
public HttpURLConnection getRequestConn() {
return mHttpURLC
&&&&& 通过HTTP协议发送GET请求
package com.everyone.android.
import java.io.IOE
import java.io.InputS
import java.net.HttpURLC
import java.net.URL;
import java.net.URLE
import java.util.M
import org.apache.http.protocol.HTTP;
import com.everyone.android.callback.ParseC
import com.everyone.android.callback.ResultC
* 功能描述:通过HTTP协议发送GET请求
* @author android_ls
public class AsyncHttpGet extends AsyncBaseRequest {
private static final long serialVersionUID = 2L;
public AsyncHttpGet(String url, Map&String, String& parameter, ParseCallback handler, ResultCallback requestCallback) throws IOException {
super(url, parameter, handler, requestCallback);
protected InputStream getRequestResult() throws IOException {
StringBuilder sb = new StringBuilder(requestUrl);
if (parameter != null && !parameter.isEmpty()) {
sb.append('?');
for (Map.Entry&String, String& entry : parameter.entrySet()) {
sb.append(entry.getKey()).append('=').append(URLEncoder.encode(entry.getValue(), HTTP.UTF_8)).append('&');
sb.deleteCharAt(sb.length() - 1);
URL url = new URL(sb.toString());
mHttpURLConn = (HttpURLConnection) url.openConnection();
mHttpURLConn.setConnectTimeout(connectTimeout);
mHttpURLConn.setRequestMethod(&GET&);
if (mHttpURLConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
return mHttpURLConn.getInputStream();
六、运行后的效果图:
&图片双缓存这块,拖了很久,这一篇博文我搞了一个通宵,终于写完了。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:222170次
积分:3208
积分:3208
排名:第4539名
原创:54篇
转载:15篇
评论:360条
本博客所有博文,是本人对在学习、工作中遇到的某些知识,个人理解进行的记录。
欢迎交流,欢迎转载,大家转载请注明出处,禁止用于商业目的。
(4)(2)(1)(1)(1)(5)(8)(2)(3)(13)(18)(11)

我要回帖

更多关于 淘宝店铺装修软件 的文章

 

随机推荐