gpt4 book ai didi

android - android 教程中的 DiskLruCache 缺少很多方法。

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:46:42 24 4
gpt4 key购买 nike

这是我正在关注的磁盘缓存教程。我已将源代码下载到 DiskLruCache,但源代码中不存在本示例中使用的所有方法。

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html#disk-cache

我是否需要自己实现这些方法,或者我是否缺少某个版本的 DiskLruCache?

最佳答案

下面是DiskLruCache的完整实现。

第一次下载DiskLruCache.java来自 AOSP。

这是我的 DiskCache.java 一个用于基本缓存操作的辅助类。

/**
* Created by Babar on 12-Aug-15.
*/
public class DiskCache
{

private Context context;

private static DiskCache diskCache;

public DiskLruCache mDiskLruCache;

private final Object mDiskCacheLock = new Object();

private BitmapProcessor bitmapProcessor;

private static final int DISK_CACHE_INDEX = 0;

public static boolean mDiskCacheStarting = true;

private static final String DISK_CACHE_SUBDIR = "ooredoo_thumbnails";

private static final int DISK_CACHE_SIZE = 1024 * 1024 * 100; // 100MB

public static DiskCache getInstance()
{
if(diskCache == null)
{
diskCache = new DiskCache();
}

return diskCache;
}

private DiskCache() {}

public void requestInit(Context context)
{
this.context = context;

bitmapProcessor = new BitmapProcessor();

new DiskCacheTask(this).execute(DiskCacheTask.INIT);
}

public void init() throws IOException {
synchronized (mDiskCacheLock)
{
if(mDiskLruCache == null || mDiskLruCache.isClosed())
{
File cacheDir = FileUtils.getDiskCacheDir(context, DISK_CACHE_SUBDIR);

if(!cacheDir.exists())
{
cacheDir.mkdir();
}

if(FileUtils.getUsableSpace(cacheDir) > DISK_CACHE_SIZE)
{
mDiskLruCache = DiskLruCache.open(cacheDir, 1, 1, DISK_CACHE_SIZE);
}
else
{
Logger.print("InitDiskCache failed: NOT enough space on disk");
}
}

mDiskCacheStarting = false; // Finished initialization
mDiskCacheLock.notifyAll(); // Wake any waiting threads
}
}


public void addBitmapToDiskCache(final String key, final Bitmap value) {
if (key == null || value == null) {
return;
}

synchronized (mDiskCacheLock)
{
if (mDiskLruCache != null) {
OutputStream out = null;

String encryptedKey = CryptoUtils.encryptToMD5(key);

Logger.print("addBitmapToDiskCache encryptToMD5: " + encryptedKey);

try {
DiskLruCache.Snapshot snapshot = mDiskLruCache.get(encryptedKey);

if (snapshot == null) {
final DiskLruCache.Editor editor = mDiskLruCache.edit(encryptedKey);

if (editor != null) {
out = editor.newOutputStream(DISK_CACHE_INDEX);

value.compress(Bitmap.CompressFormat.JPEG, 100, out);

editor.commit();
out.close();
}
} else {
snapshot.getInputStream(DISK_CACHE_INDEX).close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}

/**
* Get from disk cache.
*
* @param key Unique identifier for which item to get
* @return The bitmap if found in cache, null otherwise
*/
public Bitmap getBitmapFromDiskCache(final String key)
{
Bitmap bitmap = null;

String encryptedKey = CryptoUtils.encryptToMD5(key);

Logger.print("getBitmapFromDiskCache encryptToMD5: " + encryptedKey);

synchronized (mDiskCacheLock)
{
Logger.print("mDiskcachestarting: "+mDiskCacheStarting);
// Wait while disk cache is started from background thread
while (mDiskCacheStarting)
{
try
{
mDiskCacheLock.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}

if(mDiskLruCache != null)
{
InputStream inputStream = null;

try
{
final DiskLruCache.Snapshot snapshot = mDiskLruCache.get(encryptedKey);

if(snapshot != null)
{
Logger.print("Disk cache hit");

inputStream = snapshot.getInputStream(DISK_CACHE_INDEX);

if(inputStream != null)
{
FileDescriptor fd = ((FileInputStream) inputStream).getFD();

// Decode bitmap, but we don't want to sample so give
// MAX_VALUE as the target dimensions

bitmap = bitmapProcessor.decodeSampledBitmapFromDescriptor(fd);
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if(inputStream != null)
{
try
{
inputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
Logger.print("dCache getBitmapFromDiskCache synchronized completed");
}

Logger.print("dCache getBitmapFromDiskCache returning Bitmap");
return bitmap;
}

public void requestFlush()
{
new DiskCacheTask(this).execute(DiskCacheTask.FLUSH);
}

/**
* Flushes the disk cache associated with this ImageCache object. Note that this includes
* disk access so this should not be executed on the main/UI thread.
*/
public void flush()
{
synchronized (mDiskCacheLock)
{
if(mDiskLruCache != null)
{
try
{
mDiskLruCache.flush();

Logger.print("flush: disk cache flushed");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}

public void requestClose()
{
new DiskCacheTask(this).execute(DiskCacheTask.CLOSE);
}

/**
* Closes the disk cache associated with this ImageCache object. Note that this includes
* disk access so this should not be executed on the main/UI thread.
*/
public void close()
{
synchronized (mDiskCacheLock)
{
if(mDiskLruCache != null)
{
if(!mDiskLruCache.isClosed())
{
try
{
mDiskLruCache.close();
mDiskLruCache = null;

Logger.print("disk cache closed");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
}

/**
* Do not call this method unless you need to explicitly clear disk cache
*/
public void requestTearDown()
{
new DiskCacheTask(this).execute(DiskCacheTask.TEAR_DOWN);
}

public final void tearDown()
{
synchronized (mDiskCacheLock)
{
mDiskCacheStarting = true;

if(mDiskLruCache != null && !mDiskLruCache.isClosed())
{
try
{
mDiskLruCache.delete();

Logger.print("disk cache cleared");
}
catch (IOException e)
{
e.printStackTrace();
}

mDiskLruCache = null;
}
}
}
}

这是BitmapProcesser.java

/**
* @author Babar
* @since 15-Jun-15.
*/
public class BitmapProcessor
{
public Bitmap decodeSampledBitmapFromStream(InputStream inputStream, URL url,
int reqWidth, int reqHeight) throws IOException {
Bitmap bitmap;

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;

BitmapFactory.decodeStream(inputStream, null, options);

int width = options.outWidth;
int height = options.outHeight;

Logger.print("@Req Width: "+reqWidth);
Logger.print("@Req Height: " + reqHeight);

Logger.print("@Actual Width: "+width);
Logger.print("@Actual Height: " + height);

int sampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

options.inJustDecodeBounds = false;
options.inSampleSize = sampleSize;

inputStream = url.openStream();

bitmap = BitmapFactory.decodeStream(inputStream, null, options);

if(bitmap != null)
{
width = bitmap.getWidth();
height = bitmap.getHeight();

Logger.print("@inSample:"+sampleSize);
Logger.print("@Modified Width: "+width);
Logger.print("@Modified Height: " + height);
}

return bitmap;
}

public Bitmap decodeSampledBitmapFromDescriptor(FileDescriptor fd)
{
/*final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;

BitmapFactory.decodeFileDescriptor(fd, null, options);

options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

options.inJustDecodeBounds = false;*/

return BitmapFactory.decodeFileDescriptor(fd);

}

public Bitmap decodeSampledBitmapFromFile(String pathName, int reqWidth, int reqHeight) throws IOException {
Bitmap bitmap;

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;

BitmapFactory.decodeFile(pathName, options);

int width = options.outWidth;
int height = options.outHeight;

Logger.print("@Req Width: "+reqWidth);
Logger.print("@Req Height: " + reqHeight);

Logger.print("@Actual Width: "+width);
Logger.print("@Actual Height: " + height);

int sampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

options.inJustDecodeBounds = false;
options.inSampleSize = sampleSize;

bitmap = BitmapFactory.decodeFile(pathName, options);

if(bitmap != null)
{
width = bitmap.getWidth();
height = bitmap.getHeight();

Logger.print("@inSample:"+sampleSize);
Logger.print("@Modified Width: "+width);
Logger.print("@Modified Height: " + height);
}

return bitmap != null ? rotateBitmapIfNeeded(pathName, bitmap) : null;
}

public int calculateInSampleSize(BitmapFactory.Options options,
int requiredWidth, int requiredHeight)
{
final int width = options.outWidth;
final int height = options.outHeight;

int inSampleSize = 1;

if(width > requiredWidth || height > requiredHeight)
{
final int halfWidth = width / 2;
final int halfHeight = height / 2;

// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfWidth / inSampleSize) > requiredWidth
&&
(halfHeight / inSampleSize) > requiredHeight)
{
inSampleSize *= 2;
}
}

return inSampleSize;
}

public static Bitmap rotateBitmapIfNeeded(String pathName, Bitmap bitmap) throws IOException {
ExifInterface exifInterface = new ExifInterface(pathName);

int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);

Logger.logI("BITMAP_ORIENTATION: " + orientation, pathName);

switch (orientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:

return rotateBitmap(bitmap, 90);

case ExifInterface.ORIENTATION_ROTATE_180:

return rotateBitmap(bitmap, 180);

case ExifInterface.ORIENTATION_ROTATE_270:

return rotateBitmap(bitmap, 270);
}

return bitmap;
}

public Bitmap makeBitmapRound(Bitmap src)
{
int width = src.getWidth();
int height = src.getHeight();

Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

// Canvas canvas = new Canvas(bitmap);

BitmapShader shader = new BitmapShader(src, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);



RectF rectF = new RectF(0.0f, 0.0f, width, height);

// rect contains the bounds of the shape
// radius is the radius in pixels of the rounded corners
// paint contains the shader that will texture the shape

Canvas canvas = new Canvas(src);

canvas.drawRoundRect(rectF, 30, 30, paint);

return src;
}

public static Bitmap rotateBitmap(Bitmap bitmap, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);

return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
}

这是CryptoUtils.java

/**
* @author Babar
* @since 29-Jun-15.
*/
public class CryptoUtils
{
private static final String MD5_ALGO = "MD5";


public static String encryptToMD5(String text)
{
try
{
java.security.MessageDigest md = java.security.MessageDigest.getInstance(MD5_ALGO);
md.update(text.getBytes());

byte[] bytes = md.digest();

String hex = bytesToHexString(bytes);

return hex;
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();

return String.valueOf(text.hashCode());
}
}

private static String bytesToHexString(byte[] bytes)
{
StringBuffer sb = new StringBuffer();

for(int i = 0; i < bytes.length; i++)
{
String hex = Integer.toHexString(0xFF & bytes[i]);

if(hex.length() == 1)
{
sb.append('0');
}

sb.append(hex);
}

return sb.toString();
}

public static String encodeToBase64(String str) {
String tmp = "";
if(isNotNullOrEmpty(str)) {
try {
tmp = new String(Base64.encode(str.getBytes(), Base64.DEFAULT)).trim();
} catch(Throwable e) {
e.printStackTrace();
}
}
return tmp;
}
}

这是DiskCacheTask.java

/**
* Created by Babar on 12-Aug-15.
*/
public class DiskCacheTask extends BaseAsyncTask<Integer, Void, Void>
{
private DiskCache diskCache;

public static final int INIT = 1;

public static final int FLUSH = 2;

public static final int CLOSE = 3;

public static final int TEAR_DOWN = 4;

public static final int REMOVE = 5;

public DiskCacheTask(DiskCache diskCache)
{
this.diskCache = diskCache;
}

@Override
protected Void doInBackground(Integer... params)
{
switch (params[0])
{
case INIT:

try
{
diskCache.init();
}
catch (IOException e)
{
e.printStackTrace();
}

break;

case FLUSH:

diskCache.flush();

break;

case CLOSE:

diskCache.close();

break;

case TEAR_DOWN:

diskCache.tearDown();

break;

case REMOVE:

diskCache.remove();

break;
}

return null;
}
}

要初始化缓存,只需调用 new DiskCache().getInstance().requestInit(); 最好从 MainActivity 的 onCreate() 调用。另请注意,磁盘操作应在单独的线程中完成,例如 HandlerAsyncTask。因此,无论何时您想向磁盘缓存添加位图/从磁盘缓存获取位图,都可以从工作线程执行此操作。

关于android - android 教程中的 DiskLruCache 缺少很多方法。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18453490/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com