android 二級快取(單一原則與開閉原則)
阿新 • • 發佈:2019-01-24
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; privateImageCache 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原始碼設計模式)
開閉原則: