Android图片缓存

android实现图片缓存的全部代码,对于ListView这样需要加载大量图片的非常实用

具体用法:

ImageManager.from(Context).displayImage(ImageView,
R.drawable.photo_bg, 500, 500, chuyangTmp, chuyangCurr);

ImageManager.from(Context).displayImage(ImageView,
R.drawable.photo_bg, 500, 500);

因为我的图片是以字符串的形式下载的,代码中涉及到Bitmap的地方要做相应转换处理,下面上代码

import java.io.File;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

import org.ksoap2.serialization.SoapObject;
import org.vstinspection.activity.uihelper.ImageConvertUtil;
import org.vstinspection.application.VstInspectionApplication;
import org.vstinspection.entity.FileInfoBean;
import org.vstinspection.network.RequestDataTask1;
import org.vstinspection.utils.StringUtil;

import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.support.v4.util.LruCache;
import android.widget.ImageView;

public class ImageManager {

private static ImageManager imageManager;
public LruCache<String, Bitmap> mMemoryCache;
private static final int DISK_CACHE_SIZE = 1024 * 1024 * 20; // 10MB
private static final String DISK_CACHE_SUBDIR = "vsstoo";
public DiskLruCache mDiskCache;
private static VstInspectionApplication myapp;

private static ArrayList<FileInfoBean> list;

/** 图片加载队列,后进先出 */
private Stack<ImageRef> mImageQueue = new Stack<ImageRef>();

/** 图片请求队列,先进先出,用于存放已发送的请求。 */
private Queue<ImageRef> mRequestQueue = new LinkedList<ImageRef>();

/** 图片加载线程消息处理器 */
private Handler mImageLoaderHandler;

/** 图片加载线程是否就绪 */
private boolean mImageLoaderIdle = true;

/** 请求图片 */
private static final int MSG_REQUEST = 1;
/** 图片加载完成 */
private static final int MSG_REPLY = 2;
/** 中止图片加载线程 */
private static final int MSG_STOP = 3;
/** 如果图片是从网络加载,则应用渐显动画,如果从缓存读出则不应用动画 */
private boolean isFromNet = true;

/**
* 获取单例,只能在UI线程中使用。

* @param context
* @return
*/
public static ImageManager from(Context context) {

// 如果不在ui线程中,则抛出异常
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new RuntimeException("Cannot instantiate outside UI thread.");
}

if (myapp == null) {
myapp = (VstInspectionApplication) context.getApplicationContext();
}

if (imageManager == null) {
imageManager = new ImageManager(myapp);
}
if (list == null) {
list = new ArrayList<FileInfoBean>();
}

return imageManager;
}

/**
* 私有构造函数,保证单例模式

* @param context
*/
private ImageManager(Context context) {
int memClass = ((ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
memClass = memClass > 32 ? 32 : memClass;
// 使用可用内存的1/8作为图片缓存
final int cacheSize = 1024 * 1024 * memClass / 8;

mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {

protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}

};

File cacheDir = DiskLruCache
.getDiskCacheDir(context, DISK_CACHE_SUBDIR);
mDiskCache = DiskLruCache.openCache(context, cacheDir, DISK_CACHE_SIZE);
}

/**
* 存放图片信息
*/
class ImageRef {

/** 图片对应ImageView控件 */
ImageView imageView;
/** 图片名称 */
String fileName;
/** 图片缓存路径 */
String filePath;
/** 默认图资源ID */
int resId;

// int width = 0;
// int height = 0;

/**
* 构造函数

* @param imageView
* @param url
* @param resId
* @param filePath
*/
ImageRef(ImageView imageView, String fileName, String filePath,
int resId) {
this.imageView = imageView;
this.fileName = fileName;
this.filePath = filePath;
this.resId = resId;
}

// ImageRef(ImageView imageView, String fileName, String filePath,
// int resId, int width, int height) {
// this.imageView = imageView;
// this.fileName = fileName;
// this.filePath = filePath;
// this.resId = resId;
// this.width = width;
// this.height = height;
// }
}

/**
* 显示图片

* @param imageView
* @param fileName
* @param resId
*/
public void displayImage(ImageView imageView, String fileName, int resId) {
if (imageView == null) {
return;
}
if (imageView.getTag() != null
&& imageView.getTag().toString().equals(fileName)) {
return;
}
if (resId >= 0) {
if (imageView.getBackground() == null) {
imageView.setBackgroundResource(resId);
}
imageView.setImageDrawable(null);
}
if (StringUtil.isEmpty(fileName)) {
return;
}

// 添加url tag
imageView.setTag(fileName);

// 读取map缓存
Bitmap bitmap = mMemoryCache.get(fileName);
if (bitmap != null) {
setImageBitmap(imageView, bitmap, false);
return;
}

// 生成文件名
String filePath = fileNameToFilePath(fileName);
if (filePath == null) {
return;
}

queueImage(new ImageRef(imageView, fileName, filePath, resId));
}

/**
* 显示图片固定大小图片的缩略图,一般用于显示列表的图片,可以大大减小内存使用

* @param imageView
*            加载图片的控件
* @param url
*            加载地址
* @param resId
*            默认图片
* @param width
*            指定宽度
* @param height
*            指定高度
*/
public void displayImage(ImageView imageView, String fileName, int resId,
int width, int height) {
if (imageView == null) {
return;
}
if (resId >= 0) {

if (imageView.getBackground() == null) {
imageView.setBackgroundResource(resId);
}
imageView.setImageDrawable(null);

}
if (StringUtil.isEmpty(fileName)) {
return;
}
list.clear();

// 添加url tag
imageView.setTag(fileName);
// 读取map缓存
Bitmap bitmap = mMemoryCache.get(fileName);
if (bitmap != null) {
setImageBitmap(imageView, bitmap, false);
return;
}

// 生成文件名
String filePath = fileNameToFilePath(fileName);
if (StringUtil.isEmpty(filePath)) {
return;
}
queueImage(new ImageRef(imageView, fileName, filePath, resId));
// queueImage(new ImageRef(imageView, fileName, filePath, resId, width,
// height));
}

public void displayImage(ImageView imageView, int resId, int width,
int height, ArrayList<FileInfoBean> list1, int current) {
String fileName = list1.get(current).getFILENAME();
if (imageView == null) {
return;
}
if (resId >= 0) {

if (imageView.getBackground() == null) {
imageView.setBackgroundResource(resId);
}
imageView.setImageDrawable(null);

}
Bitmap bitmap;
String content = list1.get(current).getBitmap();
if (!StringUtil.isEmpty(content)) {
bitmap = ImageConvertUtil.convertStringToBitmap(content);
setImageBitmap(imageView, bitmap, false);
return;
}

// 添加url tag
imageView.setTag(fileName);
// 读取map缓存
bitmap = mMemoryCache.get(fileName);
if (bitmap != null) {
setImageBitmap(imageView, bitmap, false);
return;
}

// 生成文件名
String filePath = fileNameToFilePath(fileName);
if (StringUtil.isEmpty(filePath)) {
return;
}
list.clear();
list.addAll(list1);
queueImage(new ImageRef(imageView, fileName, filePath, resId));
// queueImage(new ImageRef(imageView, fileName, filePath, resId, width,
// height));
}

/**
* 入队,后进先出

* @param imageRef
*/
public void queueImage(ImageRef imageRef) {
// 删除已有ImageView
Iterator<ImageRef> iterator = mImageQueue.iterator();
while (iterator.hasNext()) {
if (iterator.next().imageView == imageRef.imageView) {
iterator.remove();
}
}

// 添加请求
mImageQueue.push(imageRef);
sendRequest();
}

/**
* 发送请求
*/
private void sendRequest() {
// 开启图片加载线程
if (mImageLoaderHandler == null) {
HandlerThread imageLoader = new HandlerThread("image_loader");
imageLoader.start();
mImageLoaderHandler = new ImageLoaderHandler(
imageLoader.getLooper());
}

// 发送请求
if (mImageLoaderIdle && mImageQueue.size() > 0) {
ImageRef imageRef = mImageQueue.pop();
Message message = mImageLoaderHandler.obtainMessage(MSG_REQUEST,
imageRef);
mImageLoaderHandler.sendMessage(message);
mImageLoaderIdle = false;
mRequestQueue.add(imageRef);
}
}

/**
* 图片加载线程
*/
class ImageLoaderHandler extends Handler {

public ImageLoaderHandler(Looper looper) {
super(looper);
}

public void handleMessage(Message msg) {
if (msg == null) {
return;
}
switch (msg.what) {
case MSG_REQUEST: // 收到请求
Bitmap bitmap = null;
if (msg.obj != null && msg.obj instanceof ImageRef) {

ImageRef imageRef = (ImageRef) msg.obj;
String fileName = imageRef.fileName;
if (StringUtil.isEmpty(fileName)) {
return;
}
// 如果本地url即读取sd相册图片,则直接读取,不用经过DiskCache
if (fileName.toLowerCase().contains("dcim")) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inSampleSize = 1;
opt.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, opt);
int bitmapSize = opt.outHeight * opt.outWidth * 4;
opt.inSampleSize = bitmapSize / (1000 * 2000);
opt.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(fileName, opt);
isFromNet = true;
} else {
bitmap = mDiskCache.get(fileName);
}
if (bitmap != null) {
// ToolUtil.log("从disk缓存读取");
// 写入map缓存
// if (imageRef.width != 0 && imageRef.height != 0) {
// if (mMemoryCache.get(fileName + imageRef.width
// + imageRef.height) == null) {
// mMemoryCache.put(fileName + imageRef.width
// + imageRef.height, bitmap);
// }
// } else {
if (mMemoryCache.get(fileName) == null) {
mMemoryCache.put(fileName, bitmap);
}
// }
if (list != null && list.size() > 0) {
String content = ImageConvertUtil
.convertImageToString(bitmap);
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getFILENAME()
.equals(imageRef.fileName)) {
list.get(i).setBitmap(content);
break;
}
}
}
if (mImageManagerHandler != null) {
Message message = mImageManagerHandler
.obtainMessage(MSG_REPLY, bitmap);
mImageManagerHandler.sendMessage(message);
}

} else {

//根据图片名称从网络下载图片,这里需要根据实际做相应修改

//RequestDataTask  是一个异步任务,因为提供接口的是一个奇葩,用webservice的形式,将图片转换成字符串以后下载

RequestDataTask  task = new RequestDataTask(
new downloadHandler(imageRef, fileName));
task.execute(new String[] { "GetImage",
"imgFileName@" + fileName });

}
}
break;
case MSG_STOP: // 收到终止指令
Looper.myLooper().quit();
break;
}
}
}

private class downloadHandler extends Handler {
private ImageRef imageRef;
private String fileName;

public downloadHandler(ImageRef imageRef, String fileName) {
this.imageRef = imageRef;
this.fileName = fileName;
}

@Override
public void handleMessage(Message msg) {
SoapObject obj = (SoapObject) msg.obj;
if (obj != null) {
String re = obj.getPropertyAsString(0);
if (!StringUtil.isEmpty(re)) {
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getFILENAME()
.equals(imageRef.fileName)) {
list.get(i).setBitmap(re);
break;
}
}
}
Bitmap bitmap = null;
bitmap = ImageConvertUtil.convertStringToBitmap(re);
if (bitmap != null && fileName != null) {
// 写入SD卡
// if (imageRef.width != 0 && imageRef.height != 0) {
// mDiskCache.put(fileName + imageRef.width
// + imageRef.height, bitmap);
// mMemoryCache.put(fileName + imageRef.width
// + imageRef.height, bitmap);
// } else {
mDiskCache.put(fileName, bitmap);
mMemoryCache.put(fileName, bitmap);
// }
isFromNet = true;
}
if (mImageManagerHandler != null) {
Message message = mImageManagerHandler.obtainMessage(
MSG_REPLY, bitmap);
mImageManagerHandler.sendMessage(message);
}
}
}
}
}

/** UI线程消息处理器 */
private Handler mImageManagerHandler = new Handler() {

@Override
public void handleMessage(Message msg) {
if (msg != null) {
switch (msg.what) {
case MSG_REPLY: // 收到应答
do {
ImageRef imageRef = mRequestQueue.remove();

if (imageRef == null)
break;
if (imageRef.imageView == null
|| imageRef.imageView.getTag() == null
|| imageRef.fileName == null)
break;
if (!(msg.obj instanceof Bitmap) || msg.obj == null) {
break;
}
Bitmap bitmap = (Bitmap) msg.obj;
// 非同一ImageView
if (!(imageRef.fileName)
.equals((String) imageRef.imageView.getTag())) {
break;
}
setImageBitmap(imageRef.imageView, bitmap, isFromNet);
isFromNet = false;

} while (false);
break;
}
}
// 设置闲置标志
mImageLoaderIdle = true;
// 若服务未关闭,则发送下一个请求。
if (mImageLoaderHandler != null) {
sendRequest();
}
}
};

/**
* 添加图片显示渐现动画

*/
private void setImageBitmap(ImageView imageView, Bitmap bitmap,
boolean isTran) {
if (isTran) {
final TransitionDrawable td = new TransitionDrawable(
new Drawable[] {
new ColorDrawable(android.R.color.transparent),
new BitmapDrawable(bitmap) });
td.setCrossFadeEnabled(true);
imageView.setImageDrawable(td);
td.startTransition(300);
} else {
imageView.setImageBitmap(bitmap);
}
}

/**
* 根据url生成缓存文件完整路径名

* @param url
* @return
*/
public String fileNameToFilePath(String fileName) {
// 扩展名位置
int index = fileName.lastIndexOf('.');
if (index == -1) {
return null;
}
StringBuilder filePath = new StringBuilder();
// 图片存取路径
filePath.append(myapp.getCacheDir().toString()).append('/');
// 图片文件名
filePath.append(MD5.Md5(fileName)).append(fileName.substring(index));
return filePath.toString();
}

/**
* Activity#onStop后,ListView不会有残余请求。
*/
public void stop() {
// 清空请求队列
mImageQueue.clear();
}

/**
* 刷新缓存里的bitmap(被重新上传过的更新fileName,被删除的从缓存去除)

* @param oldName
*            原来的图片名称
* @param newName
*            新的图片名称
* @param content
*            新的图片字符串
*/

public void reset(String oldName, String newName, String content) {

if (mDiskCache.get(oldName) != null) {
mDiskCache.remove(oldName);
}
if (mMemoryCache.get(oldName) != null) {
mMemoryCache.remove(oldName);
}
if (!StringUtil.isEmpty(content)) {
Bitmap bitmap = ImageConvertUtil.convertStringToBitmap(content);
mDiskCache.put(newName, bitmap);
mMemoryCache.put(newName, bitmap);
}
}

}

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;


/**
 * A simple disk LRU bitmap cache to illustrate how a disk cache would be used
 * for bitmap caching. A much more robust and efficient disk LRU cache solution
 * can be found in the ICS source code
 * (libcore/luni/src/main/java/libcore/io/DiskLruCache.java) and is preferable
 * to this simple implementation.
 */
public class DiskLruCache {
private static final String CACHE_FILENAME_PREFIX = "cache_";
private static final int MAX_REMOVALS = 4;
private static final int INITIAL_CAPACITY = 32;
private static final float LOAD_FACTOR = 0.75f;

private final File mCacheDir;
private int cacheSize = 0;
private int cacheByteSize = 0;
private final int maxCacheItemSize = 64; // 64 item default
private long maxCacheByteSize = 1024 * 1024 * 5; // 5MB default
private CompressFormat mCompressFormat = CompressFormat.JPEG;
private int mCompressQuality = 100;
private final int IO_BUFFER_SIZE = 4 * 1024;

private final Map<String, String> mLinkedHashMap = Collections
.synchronizedMap(new LinkedHashMap<String, String>(
INITIAL_CAPACITY, LOAD_FACTOR, true));

/**
* A filename filter to use to identify the cache filenames which have
* CACHE_FILENAME_PREFIX prepended.
*/
private static final FilenameFilter cacheFileFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
return filename.startsWith(CACHE_FILENAME_PREFIX);
}
};

/**
* Used to fetch an instance of DiskLruCache.

* @param context
* @param cacheDir
* @param maxByteSize
* @return
*/
public static DiskLruCache openCache(Context context, File cacheDir,
long maxByteSize) {
if (!cacheDir.exists()) {
cacheDir.mkdir();
}

if (cacheDir.isDirectory() && cacheDir.canWrite()) {
return new DiskLruCache(cacheDir, maxByteSize);
}

return null;
}

/**
* Constructor that should not be called directly, instead use
* {@link DiskLruCache#openCache(Context, File, long)} which runs some extra
* checks before creating a DiskLruCache instance.

* @param cacheDir
* @param maxByteSize
*/
private DiskLruCache(File cacheDir, long maxByteSize) {
mCacheDir = cacheDir;
maxCacheByteSize = maxByteSize;
}

/**
* Add a bitmap to the disk cache.

* @param key
*            A unique identifier for the bitmap.
* @param data
*            The bitmap to store.
*/
public void put(String key, Bitmap data) {
synchronized (mLinkedHashMap) {
if (mLinkedHashMap.get(key) == null) {
try {
final String file = createFilePath(mCacheDir, key);
if (writeBitmapToFile(data, file)) {
put(key, file);
flushCache();
}
} catch (final FileNotFoundException e) {
} catch (final IOException e) {
}
}
}
}

void put(String key, String file) {
mLinkedHashMap.put(key, file);
cacheSize = mLinkedHashMap.size();
cacheByteSize += new File(file).length();
}

/**
* Flush the cache, removing oldest entries if the total size is over the
* specified cache size. Note that this isn't keeping track of stale files
* in the cache directory that aren't in the HashMap. If the images and keys
* in the disk cache change often then they probably won't ever be removed.
*/
private void flushCache() {
Entry<String, String> eldestEntry;
File eldestFile;
long eldestFileSize;
int count = 0;

while (count < MAX_REMOVALS
&& (cacheSize > maxCacheItemSize || cacheByteSize > maxCacheByteSize)) {
eldestEntry = mLinkedHashMap.entrySet().iterator().next();
eldestFile = new File(eldestEntry.getValue());
eldestFileSize = eldestFile.length();
mLinkedHashMap.remove(eldestEntry.getKey());
eldestFile.delete();
cacheSize = mLinkedHashMap.size();
cacheByteSize -= eldestFileSize;
count++;
}
}

/**
* Get an image from the disk cache.

* @param key
*            The unique identifier for the bitmap
* @return The bitmap or null if not found
*/
public Bitmap get(String key) {
synchronized (mLinkedHashMap) {
try {
final String file = mLinkedHashMap.get(key);
if (file != null) {
return BitmapFactory.decodeFile(file);
} else {
final String existingFile = createFilePath(mCacheDir, key);
if (new File(existingFile).exists()) {
put(key, existingFile);
return BitmapFactory.decodeFile(existingFile);
}
}
} catch (OutOfMemoryError e) {
}
return null;
}
}

public void remove(String key) {
synchronized (mLinkedHashMap) {
final String existingFile = createFilePath(mCacheDir, key);
File file = new File(existingFile);
if (file.exists()) {
file.delete();
mLinkedHashMap.remove(key);
flushCache();
}
}
}

/**
* Checks if a specific key exist in the cache.

* @param key
*            The unique identifier for the bitmap
* @return true if found, false otherwise
*/
public boolean containsKey(String key) {
// See if the key is in our HashMap
if (mLinkedHashMap.containsKey(key)) {
return true;
}

// Now check if there's an actual file that exists based on the key
final String existingFile = createFilePath(mCacheDir, key);
if (new File(existingFile).exists()) {
// File found, add it to the HashMap for future use
put(key, existingFile);
return true;
}
return false;
}

/**
* Removes all disk cache entries from this instance cache dir
*/
public void clearCache() {
DiskLruCache.clearCache(mCacheDir);
}

/**
* Removes all disk cache entries from the application cache directory in
* the uniqueName sub-directory.

* @param context
*            The context to use
* @param uniqueName
*            A unique cache directory name to append to the app cache
*            directory
*/
public static void clearCache(Context context, String uniqueName) {
File cacheDir = getDiskCacheDir(context, uniqueName);
clearCache(cacheDir);
}

/**
* Removes all disk cache entries from the given directory. This should not
* be called directly, call {@link DiskLruCache#clearCache(Context, String)}
* or {@link DiskLruCache#clearCache()} instead.

* @param cacheDir
*            The directory to remove the cache files from
*/
private static void clearCache(File cacheDir) {
final File[] files = cacheDir.listFiles(cacheFileFilter);
for (int i = 0; i < files.length; i++) {
files[i].delete();
}
}

/**
* Get a usable cache directory (external if available, internal otherwise).

* @param context
*            The context to use
* @param uniqueName
*            A unique directory name to append to the cache dir
* @return The cache dir
*/
public static File getDiskCacheDir(Context context, String uniqueName) {


// Check if media is mounted or storage is built-in, if so, try and use
// external cache dir
// otherwise use internal cache dir
final String cachePath = context.getCacheDir().getPath();

return new File(cachePath + File.separator + uniqueName);
}

/**
* Creates a constant cache file path given a target cache directory and an
* image key.

* @param cacheDir
* @param key
* @return
*/
public static String createFilePath(File cacheDir, String key) {
try {
// Use URLEncoder to ensure we have a valid filename, a tad hacky
// but it will do for
// this example
return cacheDir.getAbsolutePath() + File.separator
+ CACHE_FILENAME_PREFIX
+ URLEncoder.encode(key.replace("*", ""), "UTF-8");
} catch (final UnsupportedEncodingException e) {
}


return null;
}


/**
* Create a constant cache file path using the current cache directory and
* an image key.

* @param key
* @return
*/
public String createFilePath(String key) {
return createFilePath(mCacheDir, key);
}

/**
* Sets the target compression format and quality for images written to the
* disk cache.

* @param compressFormat
* @param quality
*/
public void setCompressParams(CompressFormat compressFormat, int quality) {
mCompressFormat = compressFormat;
mCompressQuality = quality;
}

/**
* Writes a bitmap to a file. Call
* {@link DiskLruCache#setCompressParams(CompressFormat, int)} first to set
* the target bitmap compression and format.

* @param bitmap
* @param file
* @return
*/
private boolean writeBitmapToFile(Bitmap bitmap, String file)
throws IOException, FileNotFoundException {

OutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(file),
IO_BUFFER_SIZE);
return bitmap.compress(mCompressFormat, mCompressQuality, out);
} finally {
if (out != null) {
out.close();
}
}
}
}

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5 {
// MD5変換
public static String Md5(String str) {
if (str != null && !str.equals("")) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
byte[] md5Byte = md5.digest(str.getBytes("UTF8"));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5Byte.length; i++) {
sb.append(HEX[(int) (md5Byte[i] & 0xff) / 16]);
sb.append(HEX[(int) (md5Byte[i] & 0xff) % 16]);
}
str = sb.toString();
} catch (NoSuchAlgorithmException e) {
} catch (Exception e) {
}
}
return str;
}
}

顺便附上图片与字符串的相互转换

import java.io.ByteArrayOutputStream;

import org.vstinspection.utils.StringUtil;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.util.Base64;


public class ImageConvertUtil {
/**
* 将图片转成string

* @param bitmap
* @return
*/
public static String convertImageToString(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();// outputstream
bitmap.compress(CompressFormat.PNG, 100, baos);
byte[] appicon = baos.toByteArray();// 转为byte数组
return Base64.encodeToString(appicon, Base64.DEFAULT);
}

/**
* 将string转换成图片

* @param st
* @return
*/
public static Bitmap convertStringToBitmap(String st) {
Bitmap bitmap = null;
if(StringUtil.isEmpty(st)){
return null;
}
try {
// out = new FileOutputStream("/sdcard/aa.jpg");
byte[] bitmapArray;
bitmapArray = Base64.decode(st, Base64.DEFAULT);
bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0,
bitmapArray.length);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值