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];
    }
 
 
 

}

 




 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM