返回顶部

收藏

Android图片异步加载

更多
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import com.mosjoy.ad.MosJoyAdApplication;
import com.mosjoy.ad.R;
import com.mosjoy.ad.utils.FileCache;
import com.mosjoy.ad.utils.ImageCache;
import com.mosjoy.ad.utils.Utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.StatFs;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

/**
 * 图片异步加载工具类
 * @author zouyb
 *
 */
public class RemoteImageView extends ImageView {

    /**
     * 下载失败最大重复次数
     */
    private static int MAX_FAILURES = 3;

    /**
     * 下载图片网址
     */
    private String mUrl;

    /**
     * 当前下载成功图片网址
     */
    private String mCurrentlyGrabbedUrl;

    /**
     * 下载失败次数
     */
    private int mFailure;

    /**
     * 默认图片资源id
     */
    private Integer mDefaultImage;

    /**
     * 上下文
     */
    private Context mContext;

    /**
     *  文件操作
     */
    private FileCache fileCache;

    private final static int MB = 1048576;

    //图片宽度
    private int pwidth=-1;
    //图片高度
    private int pheight=-1;
    //是否显示默认图片
    private boolean isShowDefault=false;
    public RemoteImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        init();
    }

    public RemoteImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        init();
    }

    public RemoteImageView(Context context) {
        super(context);
        mContext = context;
        init();
    }

    /**
     * Sharable code between constructors
     */
    private void init() {
        fileCache = new FileCache(mContext);
    }

    public void setImageUrl(String url) {
        System.out.println("width="+pwidth+",height="+pheight);
        System.out.println("url="+url);
        if(("").equals(url) || url == null||url.contains("null")){
            if(isShowDefault){
                setImageResource(R.drawable.default_image);
            }else{
                setVisibility(View.GONE);
            }
            return;
        }
        setVisibility(View.VISIBLE);
        url = url.replace("\\", "/");
        mUrl = url;
        MosJoyAdApplication instance = MosJoyAdApplication.getInstance();
        ImageCache imageCache = instance.getImageCache();
        if (imageCache.isCached(mUrl)) {
            // 图片在缓存中
            this.setImageBitmap(imageCache.get(mUrl).get());
            Log.e(MosJoyAdApplication.TAG, "从内存加载图片 " + url);
        } else {
            File f = new File(mUrl);
            Bitmap b = decodeFile(f);
            if(b != null){
                //从内存卡加载
                this.setImageBitmap(b);
                imageCache.put(mUrl,new SoftReference<Bitmap>(b));
                Log.e(MosJoyAdApplication.TAG, "从本地加载图片 " + url);
            }else{
                //防止重复下载
                //if(YYQMusicApplication.getInstance().getDownLoadImageList().contains(mUrl)) return;
                //下载图片
                Log.e(MosJoyAdApplication.TAG, "从网络下载图片 " + url);
                Map<String,Object> map = new HashMap<String,Object>();
                map.put("url", mUrl);
                map.put("file", f);
                try{
                    new DownloadTask().execute(map);
                }catch(Exception e){}
            }
        }

    }

    public void setDefaultImage(Integer resid) {
        mDefaultImage = resid;
    }

    private void loadDefaultImage() {
        if (mDefaultImage != null)
            setImageResource(mDefaultImage);
    }

    class DownloadTask extends AsyncTask<Map<String, Object>,Void, Bitmap>{

        private String mTaskUrl;
        private File f;

        @Override
        public void onPreExecute() {
            loadDefaultImage();
            super.onPreExecute();
        }

        @Override
        protected Bitmap doInBackground(Map<String, Object>... params) {
            mTaskUrl = params[0].get("url").toString();
            //YYQMusicApplication.getInstance().getDownLoadImageList().add(mTaskUrl);
            f = (File) params[0].get("file");
            try {
                Bitmap bitmap=null;
                URL imageUrl = new URL(mTaskUrl);
                HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
                conn.setConnectTimeout(30000);
                conn.setReadTimeout(30000);
                InputStream is=conn.getInputStream();
                OutputStream os = new FileOutputStream(f);
                Utils.CopyStream(is, os);
                os.close();
                bitmap = decodeFile(f);
                return bitmap;
            } catch(FileNotFoundException fileNotFoundException){
                fileNotFoundException.printStackTrace();
                return null;
            }
            catch (Exception ex){
               ex.printStackTrace();
            }
            return null;
        }

        @Override
        public void onPostExecute(Bitmap b) {
            super.onPostExecute(b);
            if(b == null){
                //下载失败,继续下载
                //RemoteImageView.this.setImageUrl(mTaskUrl);
            }else{
                //下载成功
                MosJoyAdApplication.getInstance().getImageCache().put(mTaskUrl, new SoftReference<Bitmap>(b));
                RemoteImageView.this.setImageBitmap(b);            
                mCurrentlyGrabbedUrl = mTaskUrl;               
            }
        }

    };

    /**
     * 解码图片
     * @param f
     * @return
     */
    private Bitmap decodeFile(File f) {
        if(!f.exists()){
            return null;
        }
        if(pwidth>0&amp;&amp;pheight>0){
            System.out.println("加载缩略图");
            return decodeFile(f, pwidth, pheight);
        }
        try {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 1;
            return BitmapFactory.decodeFile(f.getAbsolutePath(), options);
        } catch (Exception e) {
        }
        return null;
    }

    private int freeSpaceOnSd() {
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
                .getPath());
        double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat
                .getBlockSize()) / MB;

        return (int) sdFreeMB;
    }

    private Bitmap decodeFile(File file,int width,int height){
        BitmapFactory.Options options=new BitmapFactory.Options();
        int scale=1;
        if(width>0||height>0){
            //设置次参数为true,解码时返回的Bitmap为空,不分配内存
            options.inJustDecodeBounds=true;
            BitmapFactory.decodeFile(file.getAbsolutePath(), options);
            //得到原始图片的宽度和高度
            int outWidth=options.outWidth;
            int outHeight=options.outHeight;
            while(true){
                if((width>0&amp;&amp;outWidth/2<width)||(height>0&amp;&amp;outHeight/2<height)){
                    break;
                }
                outWidth/=2;
                outHeight/=2;
                scale*=2;
            }
        }
        //缩放比例为1/scale
        options.inSampleSize=scale;
        options.inJustDecodeBounds=false;
        //处理之后,加载进内存的就是图片的缩略图
        return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
    }

    public void setPwidth(int pwidth) {
        this.pwidth = pwidth;
    }

    public void setPheight(int pheight) {
        this.pheight = pheight;
    }

    public void setShowDefault(boolean isShowDefault) {
        this.isShowDefault = isShowDefault;
    }

}

标签:java

收藏

0人收藏

支持

0

反对

0

发表评论