Android使用非同步下載快取圖片
阿新 • • 發佈:2018-11-09
PicUtil.java
package com.example.updateUtil; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader.TileMode; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.Log; public class PicUtil { private static final String TAG = "PicUtil"; /** * 根據一個網路連線(URL)獲取bitmapDrawable影象 * * @param imageUri * @return */ public static BitmapDrawable getfriendicon(URL imageUri) { BitmapDrawable icon = null; try { HttpURLConnection hp = (HttpURLConnection) imageUri .openConnection(); icon = new BitmapDrawable(hp.getInputStream());// 將輸入流轉換成bitmap hp.disconnect();// 關閉連線 } catch (Exception e) { } return icon; } /** * 根據一個網路連線(String)獲取bitmapDrawable影象 * * @param imageUri * @return */ public static BitmapDrawable getcontentPic(String imageUri) { URL imgUrl = null; try { imgUrl = new URL(imageUri); } catch (MalformedURLException e1) { e1.printStackTrace(); } BitmapDrawable icon = null; try { HttpURLConnection hp = (HttpURLConnection) imgUrl.openConnection(); icon = new BitmapDrawable(hp.getInputStream());// 將輸入流轉換成bitmap hp.disconnect();// 關閉連線 } catch (Exception e) { } return icon; } /** * 根據一個網路連線(URL)獲取bitmap影象 * * @param imageUri * @return */ public static Bitmap getusericon(URL imageUri) { // 顯示網路上的圖片 URL myFileUrl = imageUri; Bitmap bitmap = null; try { HttpURLConnection conn = (HttpURLConnection) myFileUrl .openConnection(); conn.setDoInput(true); conn.connect(); InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); is.close(); } catch (IOException e) { e.printStackTrace(); } return bitmap; } /** * 根據一個網路連線(String)獲取bitmap影象 * * @param imageUri * @return * @throws MalformedURLException */ public static Bitmap getbitmap(String imageUri) { // 顯示網路上的圖片 Bitmap bitmap = null; try { URL myFileUrl = new URL(imageUri); HttpURLConnection conn = (HttpURLConnection) myFileUrl .openConnection(); conn.setDoInput(true); conn.connect(); InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); is.close(); Log.i(TAG, "image download finished." + imageUri); } catch (IOException e) { e.printStackTrace(); return null; } return bitmap; } /** * 下載圖片 同時寫道本地快取檔案中 * * @param context * @param imageUri * @return * @throws MalformedURLException */ public static Bitmap getbitmapAndwrite(String imageUri,Context context) { Bitmap bitmap = null; try { // 顯示網路上的圖片 URL myFileUrl = new URL(imageUri); HttpURLConnection conn = (HttpURLConnection) myFileUrl .openConnection(); conn.setDoInput(true); conn.connect(); InputStream is = conn.getInputStream(); File cacheFile = FileUtil.getCacheFile(imageUri,context); BufferedOutputStream bos = null; bos = new BufferedOutputStream(new FileOutputStream(cacheFile)); Log.i(TAG, "write file to " + cacheFile.getCanonicalPath()); byte[] buf = new byte[1024]; int len = 0; // 將網路上的圖片儲存到本地 while ((len = is.read(buf)) > 0) { bos.write(buf, 0, len); } is.close(); bos.close(); // 從本地載入圖片 bitmap = BitmapFactory.decodeFile(cacheFile.getCanonicalPath()); // String name = MD5Util.MD5(imageUri); } catch (IOException e) { e.printStackTrace(); } return bitmap; } public static boolean downpic(String picName, Bitmap bitmap) { boolean nowbol = false; try { File saveFile = new File("/mnt/sdcard/download/weibopic/" + picName + ".png"); if (!saveFile.exists()) { saveFile.createNewFile(); } FileOutputStream saveFileOutputStream; saveFileOutputStream = new FileOutputStream(saveFile); nowbol = bitmap.compress(Bitmap.CompressFormat.PNG, 100, saveFileOutputStream); saveFileOutputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return nowbol; } public static void writeTofiles(Context context, Bitmap bitmap, String filename) { BufferedOutputStream outputStream = null; try { outputStream = new BufferedOutputStream(context.openFileOutput( filename, Context.MODE_PRIVATE)); bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); } catch (FileNotFoundException e) { e.printStackTrace(); } } /** * 將檔案寫入快取系統中 * * @param filename * @param is * @return */ public static String writefile(Context context, String filename, InputStream is) { BufferedInputStream inputStream = null; BufferedOutputStream outputStream = null; try { inputStream = new BufferedInputStream(is); outputStream = new BufferedOutputStream(context.openFileOutput( filename, Context.MODE_PRIVATE)); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, length); } } catch (Exception e) { } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (outputStream != null) { try { outputStream.flush(); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return context.getFilesDir() + "/" + filename + ".jpg"; } // 放大縮小圖片 public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); Matrix matrix = new Matrix(); float scaleWidht = ((float) w / width); float scaleHeight = ((float) h / height); matrix.postScale(scaleWidht, scaleHeight); Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); return newbmp; } // 將Drawable轉化為Bitmap public static Bitmap drawableToBitmap(Drawable drawable) { int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(width, height, drawable .getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, width, height); drawable.draw(canvas); return bitmap; } // 獲得圓角圖片的方法 public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) { if(bitmap == null){ return null; } Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; 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); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } // 獲得帶倒影的圖片方法 public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) { final int reflectionGap = 4; int width = bitmap.getWidth(); int height = bitmap.getHeight(); Matrix matrix = new Matrix(); matrix.preScale(1, -1); Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2, width, height / 2, matrix, false); Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Config.ARGB_8888); Canvas canvas = new Canvas(bitmapWithReflection); canvas.drawBitmap(bitmap, 0, 0, null); Paint deafalutPaint = new Paint(); canvas.drawRect(0, height, width, height + reflectionGap, deafalutPaint); canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null); Paint paint = new Paint(); LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP); paint.setShader(shader); // Set the Transfer mode to be porter duff and destination in paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); // Draw a rectangle using the paint with our linear gradient canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint); return bitmapWithReflection; } }
FileUtil.java
package com.example.updateUtil; import java.io.File; import java.io.IOException; import android.content.Context; import android.os.Environment; import android.util.Log; public class FileUtil { private static final String TAG = "FileUtil"; public static File getCacheFile(String imageUri,Context context){ File cacheFile = null; try {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
// File sdCardDir = Environment.getExternalStorageDirectory(); String fileName = getFileName(imageUri); File dir = new File(context.getFilesDir() + AsynImageLoader.CACHE_DIR);//// if (!dir.exists()) { dir.mkdirs(); }
// cacheFile = new File(sdCardDir, fileName);
cacheFile = new File(dir, fileName);
Log.i(TAG, "exists:" + cacheFile.exists() + ",dir:" + dir + ",file:" + fileName);
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "getCacheFileError:" + e.getMessage());
}
return cacheFile;
}
public static String getFileName(String path) {
int index = path.lastIndexOf("/");
return path.substring(index + 1);
}
}
AsynImageLoader.java
package com.example.mytest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
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.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;
public class AsynImageLoader {
private static final String TAG = "AsynImageLoader";
// 快取下載過的圖片的Map
private Map<String, SoftReference<Bitmap>> caches;
// 任務佇列
private List<Task> taskQueue;
private boolean isRunning = false;
static String CACHE_DIR = "/image";//////
Context context;
public AsynImageLoader(Context context){
this.context = context;
// 初始化變數
caches = new HashMap<String, SoftReference<Bitmap>>();
taskQueue = new ArrayList<AsynImageLoader.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);
}else{
imageView.setImageBitmap(bitmap);
}
}
public Bitmap loadImageAsyn(String path, ImageCallback callback){
// 判斷快取中是否已經存在該圖片
String fileName = path.substring(path.lastIndexOf("/")+1);
// Bitmap bitmap = getBitmap(fileName);
Log.i(TAG, "-------fileName-------:" + fileName);
// Log.i(TAG, "-------bitmap-------:" + bitmap);
if(caches.containsKey(path)){
// 取出軟引用
SoftReference<Bitmap> rf = caches.get(path);
// 通過軟引用,獲取圖片
Bitmap bitmap = rf.get();
// 如果該圖片已經被釋放,則將該path對應的鍵從Map中移除掉
if(bitmap == null){
caches.remove(path);
}else{
// 如果圖片未被釋放,直接返回該圖片
Log.i(TAG, "return image in cache" + path);
return bitmap;
}
}else{
// 如果快取中不常在該圖片,則建立圖片下載任務
Task task = new Task();
task.path = path;
task.callback = callback;
Log.i(TAG, "new Task ," + path);
if(!taskQueue.contains(task)){
taskQueue.add(task);
// 喚醒任務下載佇列
synchronized (runnable) {
runnable.notify();
}
}
}
// 快取中沒有圖片則返回null
return null;
}
public Bitmap getBitmap(String imageName){
try {
File dir = new File(context.getApplicationContext().getFilesDir()
.getAbsolutePath()+CACHE_DIR+"/"+imageName);////
Log.i(TAG, "------dir--------:" +dir);
if (!dir.exists()) {
// dir.mkdirs();
return null;
}else{
FileInputStream fis = new FileInputStream(dir);
Bitmap bitmap = BitmapFactory.decodeStream(fis);
return bitmap;
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
*
* @param imageView
* @param resId 圖片載入完成前顯示的圖片資源ID
* @return
*/
private ImageCallback getImageCallback(final ImageView imageView, final int resId){
return new ImageCallback() {
@Override
public void loadImage(String path, Bitmap bitmap) {
if(path.equals(imageView.getTag().toString())){
imageView.setImageBitmap(bitmap);
}else{
imageView.setImageResource(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() {
@Override
public void run() {
while(isRunning){
// 當佇列中還有未處理的任務時,執行下載任務
while(taskQueue.size() > 0){
// 獲取第一個任務,並將之從任務佇列中刪除
Task task = taskQueue.remove(0);
// 將下載的圖片新增到快取
task.bitmap = PicUtil.getbitmapAndwrite(task.path,context);
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);
}
}
}
應用--
asynImageLoader.showImageAsyn(imageView, url, resId);
刪除檔案
/**
* * 遞迴刪除檔案和資料夾 * * @param file * 要刪除的根目錄
*
*/
public void DeleteFile(File file) {
if (file.exists() == false) {
handler.sendEmptyMessage(DELETE_FAIL);
return;
} else {
if (file.isFile()) {
file.delete();
return;
}
if (file.isDirectory()) {
File[] childFile = file.listFiles();
if (childFile == null || childFile.length == 0) {
file.delete();
return;
}
for (File f : childFile) {
DeleteFile(f);
}
file.delete();
}
}
}
// 儲存檔案內容
private void writeFiles(String content) {
try {
// 開啟檔案獲取輸出流,檔案不存在則自動建立
FileOutputStream fos = context.openFileOutput(FILENAME,
Context.MODE_PRIVATE);
fos.write(content.getBytes("UTF-8"));
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// 讀取檔案內容
private String readFiles() {
String content = null;
try {
FileInputStream fis = context.openFileInput(FILENAME);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
content = baos.toString();
fis.close();
baos.close();
} catch (Exception e) {
e.printStackTrace();
}
return content;
}