简单使用Async实现图片异步加载

此部分代码来源网络,未究出处,如有冒犯,谨致歉意!

1.AsyncImageLoader.java

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import android.graphics.drawable.Drawable;
import android.os.Handler;

public class AsyncImageLoader {
    private Object lock = new Object();
    private boolean mAllowLoad = true;
    private boolean firstLoad = true;
    private int mStartLoadLimit = 0;
    private int mStopLoadLimit = 0;
    final Handler handler = new Handler();
    private HashMap<String, SoftReference<Drawable>> imageCache;

    public AsyncImageLoader() {
        imageCache = new HashMap<String, SoftReference<Drawable>>();
    }

    public void setLoadLimit(int startLoadLimit, int stopLoadLimit) {
        if (startLoadLimit > stopLoadLimit) {
            return;
        }
        mStartLoadLimit = startLoadLimit;
        mStopLoadLimit = stopLoadLimit;
    }

    public void restore() {
        mAllowLoad = true;
        firstLoad = true;
    }

    public void lock() {
        mAllowLoad = false;
        firstLoad = false;
    }

    public void unlock() {
        mAllowLoad = true;
        synchronized (lock) {
            lock.notifyAll();
        }
    }

    public Drawable loadDrawable(final Integer pos, final String imageUrl,
            final ImageCallback imageCallback) {

        // 如果不再缓存中,就加载并将其加入到缓存中
        // final Handler handler = new Handler() {
        // public void handleMessage(Message message) {
        // 这里的handleMessage是处理的消息,当已经获取到IMG后,到这里来处理,
        // 也就是将获取到的图像加载的对应的XML位置,这里将imageLoaded()函数写成一个接口的形式
        // 以至在adapter中直接将下载到的图像加载到Adater中,这些参数最终传到了Adapter里的imageLoaded函数里
        // 不在缓存中时,先开个线程获取IMG,然后返回null,以告诉调用者,现在缓存中还没有对应的IMG,正在加载
        // 你先用其它图片代替,等加载完成之后会用Message通知,然后你在imageCallback.imageLoaded()处理就可以了
        new Thread() {
            @Override
            public void run() {
                if (!mAllowLoad) {// 先阻塞线程
                    synchronized (lock) {// 加锁
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                // 如果是第一次加载XML就加载图片,对于是不是在显示范围内的加载控制放在VIEW中
                if (mAllowLoad && firstLoad) {
                    LoadImg(pos, imageUrl, imageCallback);
                }
                // 对于在显示范围内的,对其加载IMG
                if (mAllowLoad && pos <= mStopLoadLimit
                        && pos >= mStartLoadLimit) {
                    LoadImg(pos, imageUrl, imageCallback);
                }
            }
        }.start();
        return null;
    }// loadDrawable---end

    public void LoadImg(final Integer pos, final String imageUrl,
            final ImageCallback imageCallback) {
        // 首先判断是否在缓存中
        // 但有个问题是:ImageCache可能会越来越大,以至用户内存用光,所以要用SoftReference(弱引用)来实现
        if (imageCache.containsKey(imageUrl)) {
            SoftReference<Drawable> softReference = imageCache.get(imageUrl);
            final Drawable drawable = softReference.get();
            if (drawable != null) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mAllowLoad) {
                            imageCallback.onImageLoad(pos, drawable);
                        }else {
                            imageCallback.onError(pos);
                        }
                    }
                });
                return;
            }
        }
        // 尝试从URL中加载
        try {
            final Drawable drawable = loadImageFromUrl(imageUrl);
            if (drawable != null) {
                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
            }
            handler.post(new Runnable() {
                @Override
                public void run() {
                    if (mAllowLoad) {
                        imageCallback.onImageLoad(pos, drawable);
                    }
                }
            });
        } catch (IOException e) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    imageCallback.onError(pos);
                }
            });
            e.printStackTrace();
        }
    }

    // 根据URL加载图片,如果出现错误throws IOException式的错误,以便在LoadImg中捕获,执行OnError()函数
    public static Drawable loadImageFromUrl(String url) throws IOException {
        URL m;
        InputStream i = null;
        m = new URL(url);
        i = (InputStream) m.getContent();
        Drawable d = Drawable.createFromStream(i, "src");
        return d;
    }

    // 回调函数
    public interface ImageCallback {
        public void onImageLoad(Integer t, Drawable drawable);
        public void onError(Integer t);
    }
}

2.AsyncImageLoader的使用

    /** * 异步加载图片 * @param imageUrl 图片地址 * @param viewId ImageView控件Id */
    public void AsyncImageAdd(String imageUrl, final int viewId){

        AsyncImageLoader asyncImageLoader = new AsyncImageLoader();
        asyncImageLoader.loadDrawable(0,imageUrl, new ImageCallback() {
            @Override
            public void onImageLoad(Integer pos, Drawable drawable) {

                    ImageView iv = (ImageView)findViewById(viewId);
                    iv.setBackgroundDrawable(drawable);
            }
            //加载不成功的图片处理 
            @Override
            public void onError(Integer pos) {
                    ImageView iv = (ImageView)findViewById(viewId);
                    iv.setBackgroundResource(R.drawable.imageloadfail);
            }
        });
    }

即可;

你可能感兴趣的:(android,网络,异步,图片)