您的位置:首页 > 理论基础 > 计算机网络

Android异步加载网络图片

2015-12-24 12:24 375 查看
Android图片的异步加载,主要原理:

加载图片时先查看缓存中时候存在该图片,如果存在则返回该图片,否则先加载载一个默认的占位图片,同时创建一个通过网络获取图片的任务并添加,任务完成后放松消息给主线程更新界面。

使用方法:

[java] view
plaincopy

AsynImageLoader asynImageLoader = new AsynImageLoader();

asynImageLoader.showImageAsyn(imageView, imageUrl, resId);

类代码:

[java] view
plaincopy

package com.wangge.uumao.http;

import java.lang.ref.SoftReference;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import android.graphics.Bitmap;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.widget.ImageView;

import com.wangge.uumao.util.PicUtil;

public class AsynImageLoader {

private static final String TAG = "AsynImageLoader";

// 缓存下载过的图片的Map

private Map<String, SoftReference<Bitmap>> caches;

// 任务队列

private List<Task> taskQueue;

private boolean isRunning = false;

public AsynImageLoader(){

// 初始化变量

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){

// 判断缓存中是否已经存在该图片

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;

}

/**

*

* @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.getbitmap(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);

}

}

}

最后附上PicUtil类的代码,之前忘了贴这个类的代码,不好意识了~~

[java] view
plaincopy

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) {

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);

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] view
plaincopy

package com.wangge.coupon.util;

import java.io.File;

import java.io.IOException;

import android.os.Environment;

import android.util.Log;

import com.wangge.coupon.http.AsynImageLoader;

public class FileUtil {

private static final String TAG = "FileUtil";

public static File getCacheFile(String imageUri){

File cacheFile = null;

try {

if (Environment.getExternalStorageState().equals(

Environment.MEDIA_MOUNTED)) {

File sdCardDir = Environment.getExternalStorageDirectory();

String fileName = getFileName(imageUri);

File dir = new File(sdCardDir.getCanonicalPath()

+ AsynImageLoader.CACHE_DIR);

if (!dir.exists()) {

dir.mkdirs();

}

cacheFile = new File(dir, fileName);

Log.i(TAG, "exists:" + cacheFile.exists() + ",dir:" + dir + ",file:" + fileName);

}

} catch (IOException 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);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: