Android新浪微博如何下载用户头像和微博图片

由于获取图片从来是我的弱项,因此特地记录下方法

 

先建立一个被其它类调用的方法类:ShowImage()

package chj.weibo.imgutil;

import chj.weibo.app.WeiboApplication;
import android.graphics.Bitmap;
import android.widget.ImageView;

public class ShowImageLoader {

    public void showImg(ImageView view,String url){
        view.setTag(url);
        
        view.setImageBitmap(WeiboApplication.loader.get(url, getCallback(view,url)));
    }
    
    private static ImageLoaderCallback getCallback(final ImageView view,String url){
        
        return new ImageLoaderCallback() {
            
            @Override
            public void refresh(String url, Bitmap bmp) {
                if(url.equals(view.getTag().toString())){
                    view.setImageBitmap(bmp);
                }
            }
        };
    }
}

 

然后建立一个ImageLoader:

package chj.weibo.imgutil;

import java.lang.Thread.State;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import chj.weibo.app.WeiboApplication;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public class LazyImgLoader {

    public static final int SUCCESS_DOWM = 1;
    public static final String IMG_URL="img_url";
    public static final String IMG = "img";
    
    private ImageManager imgManager = new ImageManager(WeiboApplication.context);
    
    private BlockingQueue<String> urlQueue = new ArrayBlockingQueue<String>(20);
    
    private DownloadImgThread thread = new DownloadImgThread();
    
    private CallbackManager manager = new CallbackManager();
    
    public Bitmap get(String url,ImageLoaderCallback callback){
        try {
            Bitmap bmp = null;
            //首先从缓存获取
            if(imgManager.contains(url)){
                bmp = imgManager.getFromCache(url);
                return bmp;
            }
            else{
                manager.put(url, callback);
                //开始从网络下载
                startDownloadThread(url);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    private void startDownloadThread(String url) throws Exception{
        //从网络下载
        if(!urlQueue.contains(url)){
            //放入下载队伍
            urlQueue.put(url);
        }
        State s = thread.getState();
        if(s == State.NEW){
            thread.start();
        }
        //线程已经结束
        else if(s == State.TERMINATED){
            thread = new DownloadImgThread();
            thread.start();
        }
    }
    
    Handler handler = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            switch(msg.what){
            case SUCCESS_DOWM:
                Bundle b = msg.getData();
                String url  = b.getString(IMG_URL);
                Bitmap bmp = b.getParcelable(IMG);
                manager.callback(url,bmp);
            }
        }
        
    };
    
    private class DownloadImgThread extends Thread{

        private boolean isRun = true;
        
        @Override
        public void run() {
            try {
                while(isRun){
                    String u = urlQueue.poll();
                    Bitmap bmp;
                    if(null == u){
                        //下载完毕
                        break;
                    }
                    if(imgManager.getFromFile(u) == null){
                        bmp = imgManager.downloadFromNet(u);
                    }
                    else{
                        bmp = imgManager.getFromFile(u);
                    }
                    
                    Message msg = handler.obtainMessage(SUCCESS_DOWM);
                    Bundle b = msg.getData();
                    b.putString(IMG_URL, u);
                    b.putParcelable(IMG, bmp);
                    handler.sendMessage(msg);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                isRun = false;
            }
        }
        
    }
    
}

 



ImageLoader会调用一下从缓存读取图片或者从互联网下载图片的方法,因此需要一个ImageManager的类:

package chj.weibo.imgutil;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import chj.weibo.util.MD5Util;

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

public class ImageManager {

    private Context context;
    private Map<String, SoftReference<Bitmap>> imgCache ;

    public ImageManager(Context context) {
        this.context = context;
        imgCache = new HashMap<String, SoftReference<Bitmap>>(20);
    }
    
    public boolean contains(String url){
        return imgCache.containsKey(url);
    }
    
    /**
     * 从缓存获取图片
     * @param url
     * @return
     */
    public Bitmap getFromCache(String url){
        Bitmap bmp = null;
        //先从缓存读取
        bmp = this.getFromMap(url);
        if(null == bmp){
            //从文件读取
            bmp = this.getFromFile(url);
            imgCache.put(url, new SoftReference<Bitmap>(bmp));
        }
        return bmp;
    }
    
    /**
     * 从文件读取图片
     * @param url
     * @return
     */
    public Bitmap getFromFile(String url){
        Bitmap bmp = null;
        InputStream is = null;
        String fileName = MD5Util.getMD5String(url);
        try {
            is = context.openFileInput(fileName);
            if(null != is){
                bmp = BitmapFactory.decodeStream(is);
                return bmp;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }finally{
            try {
                if(is != null){
                    is.close();
                    is = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    
    /**
     * 从Map读取图片
     * @param url
     * @return
     */
    public Bitmap getFromMap(String url){
        Bitmap bmp = null;
        SoftReference<Bitmap> ref = null;
        
        synchronized (this) {
            ref = imgCache.get(url);
        }
        if(null != ref){
            bmp = ref.get();
        }
        return bmp;
    }
    
    /**
     * 从网络下载图片并把他放入文件系统中
     * @param url
     * @return
     */
    public Bitmap downloadFromNet(String url){
        if(url == null || "".equals(url)){
            return null;
        }
        
        try {
            URL u = new URL(url);
            HttpURLConnection conn =  (HttpURLConnection)u.openConnection();
            String fileName = writeToFile(url, conn.getInputStream());
            return BitmapFactory.decodeFile(fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    //将图片写入文件系统
    private String writeToFile(String fileName,InputStream is){
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        byte[] buff = new byte[1024];
        int length = 0;
        String fileNameMD5 = null;
        try {
            fileNameMD5 = MD5Util.getMD5String(fileName);
            bis = new BufferedInputStream(is);
            bos = new BufferedOutputStream(context.openFileOutput(fileNameMD5, Context.MODE_PRIVATE));
            while((length = bis.read(buff)) != -1){
                bos.write(buff, 0, length);
            }
        } catch (Exception e) {
            return null;
        }
        finally{
            try {
                if(null != is){
                    is.close();
                    is = null;
                }
                if(null != bis){
                    bis.close();
                    bis = null;
                }
                if(null != bos){
                    bos.flush();
                    bos.close();
                    bos = null;
                }
            } catch (Exception e2) {}
        }
        
        return context.getFilesDir() + "/" + fileNameMD5;
    }
}

 




然后需要一个接口做图片回调用:ImageLoaderCallback:

package chj.weibo.imgutil;

import android.graphics.Bitmap;


public interface ImageLoaderCallback {

    public void refresh(String url,Bitmap bmp);
    
}

 




最后需要一个CallbackManager:

package chj.weibo.imgutil;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import android.graphics.Bitmap;


public class CallbackManager {

    private ConcurrentHashMap<String, List<ImageLoaderCallback>> maps;
    
    public CallbackManager() {
        maps = new ConcurrentHashMap<String, List<ImageLoaderCallback>>();
    }

    public void put(String url,ImageLoaderCallback cb){
        if(!maps.contains(url)){
            maps.put(url, new ArrayList<ImageLoaderCallback>());
        }
        maps.get(url).add(cb);
    }

    public void callback(String url,Bitmap bmp){
        List<ImageLoaderCallback> callback = maps.get(url);
        if(null == callback){
            return;
        }
        for (ImageLoaderCallback c : callback) {
            c.refresh(url, bmp);
        }
    }
}

 



然后直接在需要使用的类中调用showImage即可.

由于Android的openfileoutput和input传入的字符串不可带有分隔符,因此另外需要一个类用于加密,这里采用MD5加密算法:

package chj.weibo.util;

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

public class MD5Util {

    /**
     * 16进制字符集
     */
    private static final char HEX_DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
 
    /**
     * 指定算法为MD5的MessageDigest
     */
    private static MessageDigest messageDigest = null;
 
    /**
     * 初始化messageDigest的加密算法为MD5
     */
    static
    {
        try
        {
            messageDigest = MessageDigest.getInstance("MD5");
        }
        catch(NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
    }
 
    
    /**
     * MD5加密字符串
     * @param str 目标字符串
     * @return MD5加密后的字符串
     */
    public static String getMD5String(String str)
    {
        return getMD5String(str.getBytes());
    }
 
    /**
     * MD5加密以byte数组表示的字符串
     * @param bytes 目标byte数组
     * @return MD5加密后的字符串
     */
    public static String getMD5String(byte[] bytes)
    {
        messageDigest.update(bytes);
        return bytesToHex(messageDigest.digest());
    }
     
   
 
 
    /**
     * 将字节数组转换成16进制字符串
     * @param bytes 目标字节数组
     * @return 转换结果
     */
    public static String bytesToHex(byte bytes[])
    {
        return bytesToHex(bytes, 0, bytes.length);
    }
 
    /**
     * 将字节数组中指定区间的子数组转换成16进制字符串
     * @param bytes 目标字节数组
     * @param start 起始位置(包括该位置)
     * @param end 结束位置(不包括该位置)
     * @return 转换结果
     */
    public static String bytesToHex(byte bytes[], int start, int end)
    {
        StringBuilder sb = new StringBuilder();
 
        for(int i = start; i < start + end; i++)
        {
            sb.append(byteToHex(bytes[i]));
        }
 
        return sb.toString();
    }
 
    /**
     * 将单个字节码转换成16进制字符串
     * @param bt 目标字节
     * @return 转换结果
     */
    public static String byteToHex(byte bt)
    {
        return HEX_DIGITS[(bt & 0xf0) >> 4] + "" + HEX_DIGITS[bt & 0xf];
    }
 
 
 

}

 




 

 

posted on 2012-05-06 10:56  saobchj  阅读(3828)  评论(3编辑  收藏  举报

导航