1. 程式人生 > >android 二級快取(單一原則與開閉原則)

android 二級快取(單一原則與開閉原則)



import android.content.Context;
import android.graphics.Bitmap;
import java.io.IOException;

/**
 * SD卡快取
 */
public class DiskCache implements ImageCache {
    private Context mContext;
    private ImageUtils mImageUtils;
    public DiskCache(Context context) {
        mContext = context;
        mImageUtils 
= new ImageUtils(mContext); } //獲取SD卡圖片 @Override public Bitmap getBitmap(String url) { return mImageUtils.getBitmap(url.substring(url.length() -10, url.length())); } //存入SD卡 @Override public void putBitmap(String url, Bitmap bmp) { try { mImageUtils.savaBitmap(url.substring(url.length() - 10
, url.length()), bmp); } catch (IOException e) { e.printStackTrace(); } } }
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;

/**
 * 雙快取類
 */
public class DoubleCache implements ImageCache {
    private ImageCache mMeromyCache;
    private 
ImageCache mDiskCache; private Context mContext; public DoubleCache(Context context) { mContext = context; mMeromyCache = new MemoryCache(); mDiskCache = new DiskCache(mContext); } @Override public Bitmap getBitmap(String url) { Bitmap mBitmap = mMeromyCache.getBitmap(url); if (mBitmap == null) { mBitmap = mDiskCache.getBitmap(url); } return mBitmap; } @Override public void putBitmap(String url, Bitmap bmp) { mMeromyCache.putBitmap(url.substring(url.length() -10, url.length()), bmp); mDiskCache.putBitmap(url.substring(url.length() -10, url.length()), bmp); } }

import android.graphics.Bitmap;

import java.io.IOException;

/**
 * 快取抽象介面
 */
public interface ImageCache {
    //獲取圖片
public Bitmap getBitmap(String url);
    //快取圖片
public void putBitmap(String url,Bitmap bmp)  ;
}
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.ImageView;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Administrator on 2018/3/12.
 */
public class ImageLoader {
    private Context mContext;
    //圖片快取
private ImageCache mImageCache;

    //執行緒池,執行緒數量為cpu數量
ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    Handler mUiHandler = new Handler(Looper.getMainLooper());

    //注入快取實現
public void setImageCache(ImageCache cache) {
        mImageCache = cache;
    }

    public ImageLoader(Context context) {
        mContext = context;
    }

    private void updateImageView(final ImageView imageView, final Bitmap bitmap) {
        mUiHandler.post(new Runnable() {
            @Override
public void run() {
                imageView.setImageBitmap(bitmap);
            }
        });

    }

    public void displayImageView(String iamgeUrl, ImageView imageView) {
        Bitmap bitmap = null;
        bitmap = mImageCache.getBitmap(iamgeUrl);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            return;
        }
        submitLoadRequstImage(iamgeUrl, imageView);
    }

    private void submitLoadRequstImage(final String imageUrl, final ImageView imageView) {
        imageView.setTag(imageUrl);
        mExecutorService.submit(new Runnable() {
            @Override
public void run() {
                Bitmap bitmap = downloadBitmap(imageUrl);
                if (bitmap == null) {
                    return;
                }
                if (imageView.getTag().equals(imageUrl)) {
                    updateImageView(imageView, bitmap);
                }
                mImageCache.putBitmap(imageUrl, bitmap);
            }
        });

    }

    public Bitmap downloadBitmap(String imageUrl) {
        Bitmap bitmap = null;
        try {
            URL url = new URL(imageUrl);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            bitmap = BitmapFactory.decodeStream(httpURLConnection.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }
}
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 工具類
 */
public class ImageUtils {
    /**
     * sd卡的根目錄
     */
private static String mSdRootPath = Environment.getExternalStorageDirectory().getPath();
    /**
     * 手機的快取根目錄
     */
private static String mDataRootPath = null;
    /**
     * 儲存Image的目錄名
     */
private final static String FOLDER_NAME = "/AndroidImage";


    public ImageUtils(Context context) {
        mDataRootPath = context.getCacheDir().getPath();
    }

    /**
     * 獲取儲存Image的目錄
     *
     * @return
*/
private String getStorageDirectory() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ?
                mSdRootPath + FOLDER_NAME : mDataRootPath + FOLDER_NAME;
    }

    /**
     * 儲存Image的方法,有sd卡儲存到sd卡,沒有就儲存到手機目錄
     *
     * @param fileName
* @param bitmap
* @throws IOException
     */
public void savaBitmap(String fileName, Bitmap bitmap) throws IOException {
        if (bitmap == null) {
            return;
        }
        String path = getStorageDirectory();
        File folderFile = new File(path);
        if (!folderFile.exists()) {
            folderFile.mkdir();
        }
        File file = new File(path + File.separator + fileName);
        file.createNewFile();
        FileOutputStream fos = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
    }


    /**
     * 從手機或者sd卡獲取Bitmap
     *
     * @param fileName
* @return
*/
public Bitmap getBitmap(String fileName) {
        return BitmapFactory.decodeFile(getStorageDirectory() + File.separator + fileName);
    }

    /**
     * 判斷檔案是否存在
     *
     * @param fileName
* @return
*/
public boolean isFileExists(String fileName) {
        return new File(getStorageDirectory() + File.separator + fileName).exists();
    }

    /**
     * 獲取檔案的大小
     *
     * @param fileName
* @return
*/
public long getFileSize(String fileName) {
        return new File(getStorageDirectory() + File.separator + fileName).length();
    }


    /**
     * 刪除SD卡或者手機的快取圖片和目錄
     */
public void deleteFile() {
        File dirFile = new File(getStorageDirectory());
        if (!dirFile.exists()) {
            return;
        }
        if (dirFile.isDirectory()) {
            String[] children = dirFile.list();
            for (int i = 0; i < children.length; i++) {
                new File(dirFile, children[i]).delete();
            }
        }

        dirFile.delete();
    }
}
import android.graphics.Bitmap;
import android.util.Log;
import android.util.LruCache;

import java.util.HashMap;
import java.util.Map;

/**
 * 記憶體快取
 */
public class MemoryCache implements ImageCache {
    private LruCache<String, Bitmap> mMemoryCache;

    public MemoryCache() {
        //初始化記憶體快取
int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int mCacheSize = maxMemory / 8;
        //給LruCache分配1/8 4M
mMemoryCache = new LruCache<String, Bitmap>(mCacheSize){
            //必須重寫此方法,來測量Bitmap的大小
@Override
protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes() * value.getHeight();
            }
        };
    }

    @Override
public Bitmap getBitmap(String url) {
        return mMemoryCache.get(url.substring(url.length() -10, url.length()));
    }

    @Override
public void putBitmap(String url, Bitmap bmp) {
        mMemoryCache.put(url.substring(url.length() -10, url.length()), bmp);
    }

}

使用:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        imageView = (ImageView) findViewById(R.id.xxxxxx);
        ImageLoader imageLoader = new ImageLoader(this);
        //記憶體快取
//        imageLoader.setImageCache(new MemoryCache());
//        SD卡快取
//        imageLoader.setImageCache(new DiskCache(this));
        //雙快取
imageLoader.setImageCache(new MemoryCache( ));
        imageLoader.displayImageView("http://img.showcdn.cn/uploads/allimg/160307/20-16030G15J1435.jpg", imageView);
//        //自定義快取
//        imageLoader.setImageCache(new ImageCache() {
//            @Override
//            public Bitmap getBitmap(String url) {
//                return null;
//            }
//
//            @Override
//            public void putBitmap(String url, Bitmap bmp) {
//
//            }
//        });
//        initView();
}

許可權:

<uses-permission android:name="android.permission.SET_DEBUG_APP"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

注意:targetVersion大於等於23需要做許可權申請

單一原則:(摘抄自android原始碼設計模式)


開閉原則:


import android.content.Context;
import android.graphics.Bitmap;
import java.io.IOException;

/**
 * SD卡快取
 */
public class DiskCache implements ImageCache {
    private Context mContext;
    private ImageUtils mImageUtils;
    public DiskCache(Context context) {
        mContext = context;
        mImageUtils = new ImageUtils(mContext);
    }
    //獲取SD卡圖片
@Override
public Bitmap getBitmap(String url) {
        return mImageUtils.getBitmap(url.substring(url.length() -10, url.length()));
    }
    //存入SD卡
@Override
public void putBitmap(String url, Bitmap bmp) {
        try {
            mImageUtils.savaBitmap(url.substring(url.length() - 10, url.length()), bmp);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;

/**
 * 雙快取類
 */
public class DoubleCache implements ImageCache {
    private ImageCache mMeromyCache;
    private ImageCache mDiskCache;
    private Context mContext;

    public  DoubleCache(Context context) {
        mContext = context;
        mMeromyCache = new MemoryCache();
        mDiskCache = new DiskCache(mContext);
    }

    @Override
public Bitmap getBitmap(String url) {
        Bitmap mBitmap = mMeromyCache.getBitmap(url);
        if (mBitmap == null) {
            mBitmap = mDiskCache.getBitmap(url);
        }
        return mBitmap;
    }

    @Override
public void putBitmap(String url, Bitmap bmp) {
        mMeromyCache.putBitmap(url.substring(url.length() -10, url.length()), bmp);
        mDiskCache.putBitmap(url.substring(url.length() -10, url.length()), bmp);
    }
}

import android.graphics.Bitmap;

import java.io.IOException;

/**
 * 快取抽象介面
 */
public interface ImageCache {
    //獲取圖片
public Bitmap getBitmap(String url);
    //快取圖片
public void putBitmap(String url,Bitmap bmp)  ;
}
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.ImageView;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Administrator on 2018/3/12.
 */
public class ImageLoader {
    private Context mContext;
    //圖片快取
private ImageCache mImageCache;

    //執行緒池,執行緒數量為cpu數量
ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    Handler mUiHandler = new Handler(Looper.getMainLooper());

    //注入快取實現
public void setImageCache(ImageCache cache) {
        mImageCache = cache;
    }

    public ImageLoader(Context context) {
        mContext = context;
    }

    private void updateImageView(final ImageView imageView, final Bitmap bitmap) {
        mUiHandler.post(new Runnable() {
            @Override
public void run() {
                imageView.setImageBitmap(bitmap);
            }
        });

    }

    public void displayImageView(String iamgeUrl, ImageView imageView) {
        Bitmap bitmap = null;
        bitmap = mImageCache.getBitmap(iamgeUrl);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            return;
        }
        submitLoadRequstImage(iamgeUrl, imageView);
    }

    private void submitLoadRequstImage(final String imageUrl, final ImageView imageView) {
        imageView.setTag(imageUrl);
        mExecutorService.submit(new Runnable() {
            @Override
public void run() {
                Bitmap bitmap = downloadBitmap(imageUrl);
                if (bitmap == null) {
                    return;
                }
                if (imageView.getTag().equals(imageUrl)) {
                    updateImageView(imageView, bitmap);
                }
                mImageCache.putBitmap(imageUrl, bitmap);
            }
        });

    }

    public Bitmap downloadBitmap(String imageUrl) {
        Bitmap bitmap = null;
        try {
            URL url = new URL(imageUrl);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            bitmap = BitmapFactory.decodeStream(httpURLConnection.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }
}
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 工具類
 */
public class ImageUtils {
    /**
     * sd卡的根目錄
     */
private static String mSdRootPath = Environment.getExternalStorageDirectory().getPath();
    /**
     * 手機的快取根目錄
     */
private static String mDataRootPath = null;
    /**
     * 儲存Image的目錄名
     */
private final static String FOLDER_NAME = "/AndroidImage";


    public ImageUtils(Context context) {
        mDataRootPath = context.getCacheDir().getPath();
    }

    /**
     * 獲取儲存Image的目錄
     *
     * @return
*/
private String getStorageDirectory() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ?
                mSdRootPath + FOLDER_NAME : mDataRootPath + FOLDER_NAME;
    }

    /**
     * 儲存Image的方法,有sd卡儲存到sd卡,沒有就儲存到手機目錄
     *
     * @param fileName
* @param bitmap
* @throws IOException
     */
public void savaBitmap(String fileName, Bitmap bitmap) throws IOException {
        if (bitmap == null) {
            return;
        }
        String path = getStorageDirectory();
        File folderFile = new File(path);
        if (!folderFile.exists()) {
            folderFile.mkdir();
        }
        File file = new File(path + File.separator + fileName);
        file.createNewFile();
        FileOutputStream fos = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
    }


    /**
     * 從手機或者sd卡獲取Bitmap
     *
     * @param fileName
* @return
*/
public Bitmap getBitmap(String fileName) {
        return BitmapFactory.decodeFile(getStorageDirectory() + File.separator + fileName);
    }

    /**
     * 判斷檔案是否存在
     *
     * @param fileName
* @return
*/
public boolean isFileExists(String fileName) {
        return new File(getStorageDirectory() + File.separator + fileName).exists();
    }

    /**
     * 獲取檔案的大小
     *
     * @param fileName
* @return
*/
public long getFileSize(String fileName) {
        return new File(getStorageDirectory() + File.separator + fileName).length();
    }


    /**
     * 刪除SD卡或者手機的快取圖片和目錄
     */
public void deleteFile() {
        File dirFile = new File(getStorageDirectory());
        if (!dirFile.exists()) {
            return;
        }
        if (dirFile.isDirectory()) {
            String[] children = dirFile.list();
            for (int i = 0; i < children.length; i++) {
                new File(dirFile, children[i]).delete();
            }
        }

        dirFile.delete();
    }
}
import android.graphics.Bitmap;
import android.util.Log;
import android.util.LruCache;

import java.util.HashMap;
import java.util.Map;

/**
 * 記憶體快取
 */
public class MemoryCache implements ImageCache {
    private LruCache<String, Bitmap> mMemoryCache;

    public MemoryCache() {
        //初始化記憶體快取
int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int mCacheSize = maxMemory / 8;
        //給LruCache分配1/8 4M
mMemoryCache = new LruCache<String, Bitmap>(mCacheSize){
            //必須重寫此方法,來測量Bitmap的大小
@Override
protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes() * value.getHeight();
            }
        };
    }

    @Override
public Bitmap getBitmap(String url) {
        return mMemoryCache.get(url.substring(url.length() -10, url.length()));
    }

    @Override
public void putBitmap(String url, Bitmap bmp) {
        mMemoryCache.put(url.substring(url.length() -10, url.length()), bmp);
    }

}

使用:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        imageView = (ImageView) findViewById(R.id.xxxxxx);
        ImageLoader imageLoader = new ImageLoader(this);
        //記憶體快取
//        imageLoader.setImageCache(new MemoryCache());
//        SD卡快取
//        imageLoader.setImageCache(new DiskCache(this));
        //雙快取
imageLoader.setImageCache(new MemoryCache( ));
        imageLoader.displayImageView("http://img.showcdn.cn/uploads/allimg/160307/20-16030G15J1435.jpg", imageView);
//        //自定義快取
//        imageLoader.setImageCache(new ImageCache() {
//            @Override
//            public Bitmap getBitmap(String url) {
//                return null;
//            }
//
//            @Override
//            public void putBitmap(String url, Bitmap bmp) {
//
//            }
//        });
//        initView();
}

許可權:

<uses-permission android:name="android.permission.SET_DEBUG_APP"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

注意:targetVersion大於等於23需要做許可權申請

單一原則:(摘抄自android原始碼設計模式)


開閉原則: