《Android原始碼設計模式解析與實戰》——物件導向的六大原則的圖片載入器原始碼

鋸齒流沙發表於2017-12-26
快取介面

ImageCache:

public interface ImageCache
{
	public Bitmap get(String url);
	public void put(String url,Bitmap bitmap);
}
複製程式碼
記憶體快取

MemoryCache:

public class MemoryCache implements ImageCache
{
	private LruCache<String, Bitmap> mMemoryCache;

	public MemoryCache()
	{
		initImageCache();
	}

	private void initImageCache()
	{
		//計算可使用的最大記憶體
		final int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024);
		//取1/4作為快取
		final int cacheSize = maxMemory / 4;
		mMemoryCache = new LruCache<String, Bitmap>(cacheSize)
		{
			@Override
			protected int sizeOf(String key, Bitmap value)
			{
				return value.getRowBytes() * value.getHeight() / 4;
			}
		};
	}

	@Override
	public Bitmap get(String url)
	{
		return mMemoryCache.get(url);
	}

	@Override
	public void put(String url, Bitmap bitmap)
	{
		mMemoryCache.put(url,bitmap);
	}
}
複製程式碼
磁碟快取

DiskCache :

public class DiskCache implements ImageCache
{
	static String cacheDir = "sdcard/cache/";

	@Override
	public Bitmap get(String url)
	{
		return BitmapFactory.decodeFile(cacheDir+url);
	}

	@Override
	public void put(String url, Bitmap bmp)
	{
		FileOutputStream fileOutputStream = null;
		try
		{
			fileOutputStream = new FileOutputStream(cacheDir + url);
			bmp.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			CloseUtils.closeQuitely(fileOutputStream);
			if(fileOutputStream != null)
			{
				try
				{
					fileOutputStream.close();
				}
				catch(IOException e)
				{
					e.printStackTrace();
				}
			}
		}
	}
}
複製程式碼
流工具

CloseUtils:

public class CloseUtils
{
	private CloseUtils(){}

	/**
	 * 關閉closeable物件
	 * @param closeable
	 */
	public static void closeQuitely(Closeable closeable){
		if(closeable != null){
			try
			{
				closeable.close();
			}
			catch(IOException e)
			{
				e.printStackTrace();
			}
		}
	}
}
複製程式碼
雙快取實現

DoubleCache :

/**
 * 雙快取,獲取圖片先從記憶體,記憶體沒有在從sdcard獲取
 * 快取時在記憶體和sdcard各快取一份
 */
public class DoubleCache implements ImageCache
{
	private MemoryCache mMemoryCache = new MemoryCache();
	private DiskCache mDiskCache = new DiskCache();
	@Override
	public Bitmap get(String url)
	{
		Bitmap bitmap = mMemoryCache.get(url);
		if(bitmap == null){
			bitmap = mDiskCache.get(url);
		}
		return bitmap;
	}

	@Override
	public void put(String url, Bitmap bitmap)
	{
		mMemoryCache.put(url,bitmap);
		mDiskCache.put(url,bitmap);
	}
}
複製程式碼
圖片載入器的實現

ImageLoader:

public class ImageLoader
{
	//記憶體快取
	private ImageCache mImageCache = new MemoryCache();
	//執行緒池,個數為cpu的數量
	private ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
	/**
	 * 注入快取實現
	 * @param cache
	 */
	public void setImageCache(ImageCache cache){
		this.mImageCache = cache;
	}

	//載入圖片
	public void displayImage(String url, ImageView imageView){
		Bitmap bitmap = mImageCache.get(url);
		if(bitmap != null){
			imageView.setImageBitmap(bitmap);
			return;
		}
		//沒有快取提交到執行緒池下載圖片
		submitLoadRequest(url,imageView);
	}

	private void submitLoadRequest(final String url, final ImageView imageView)
	{
		imageView.setTag(url);
		mExecutorService.submit(new Runnable()
		{
			@Override
			public void run()
			{
				Bitmap bitmap = downloadImage(url);
				if(bitmap == null){
					return;
				}
				if(imageView.getTag().equals(url)){
					imageView.setImageBitmap(bitmap);
				}
				mImageCache.put(url,bitmap);
			}
		});
	}

	/**
	 * 下載圖片
	 * @param imageUrl
	 * @return
	 */
	private Bitmap downloadImage(String imageUrl)
	{
		Bitmap mBitmap = null;
		try
		{
			URL url = new URL(imageUrl);
			final HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			mBitmap = BitmapFactory.decodeStream(conn.getInputStream());
			conn.disconnect();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return mBitmap;
	}
}
複製程式碼

相關文章