facebook twitter hatena line email

「Android/DiskLruCache」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(公式?)
(downloadしたものをcacheする)
 
(同じ利用者による、間の15版が非表示)
行17: 行17:
 
mopub
 
mopub
 
https://github.com/mopub/mopub-android-sdk/blob/master/mopub-sdk/mopub-sdk-base/src/main/java/com/mopub/common/DiskLruCache.java
 
https://github.com/mopub/mopub-android-sdk/blob/master/mopub-sdk/mopub-sdk-base/src/main/java/com/mopub/common/DiskLruCache.java
==bitmapサンプル==
 
https://developer.android.com/topic/performance/graphics/cache-bitmap#java
 
  
<pre>
+
==準備==
private DiskLruCache mDiskLruCache;
+
key部分のhogehogeはmd5やsha1などでhash化して使うと良い。
private final Object mDiskCacheLock = new Object();
+
private boolean mDiskCacheStarting = true;
+
private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
+
private static final String DISK_CACHE_SUBDIR = "thumbnails";
+
  
@Override
+
[[android/hash]] [ショートカット]
protected void onCreate(Bundle savedInstanceState) {
+
    ...
+
    // Initialize memory cache
+
    ...
+
    // Initialize disk cache on background thread
+
    File cacheDir = getDiskCacheDir(this, DISK_CACHE_SUBDIR);
+
    new InitDiskCacheTask().execute(cacheDir);
+
    ...
+
}
+
  
class InitDiskCacheTask extends AsyncTask<File, Void, Void> {
+
==使い方サンプル==
    @Override
+
<pre>
    protected Void doInBackground(File... params) {
+
String UNIQUE_CACHE_NAME = "hogehoge-cache";
        synchronized (mDiskCacheLock) {
+
int VALUE_COUNT = 1;
            File cacheDir = params[0];
+
int DISK_CACHE_INDEX = 0;
            mDiskLruCache = DiskLruCache.open(cacheDir, DISK_CACHE_SIZE);
+
String cachePath = context.getCacheDir().getPath()
            mDiskCacheStarting = false; // Finished initialization
+
File cacheDirectory =  new File(cachePath + File.separator + UNIQUE_CACHE_NAME);
            mDiskCacheLock.notifyAll(); // Wake any waiting threads
+
long diskCacheSizeBytes = 30 * 1024 * 1024; // 30 MB
        }
+
// 初期化
        return null;
+
DiskLruCache sDiskLruCache = DiskLruCache.open(
    }
+
                        cacheDirectory,
}
+
                        APP_VERSION,
 +
                        VALUE_COUNT,
 +
                        diskCacheSizeBytes);
 +
// 取得
 +
DiskLruCache.Snapshot snapshot = sDiskLruCache.get("hogehoge");
 +
final InputStream in = snapshot.getInputStream(DISK_CACHE_INDEX);
  
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
+
// 更新
    ...
+
DiskLruCache.Editor editor = sDiskLruCache.edit("hogehoge");
    // Decode image in background.
+
final OutputStream outputStream =
    @Override
+
        new BufferedOutputStream(editor.newOutputStream(DISK_CACHE_INDEX));
    protected Bitmap doInBackground(Integer... params) {
+
Streams.copyContent(content, outputStream);
        final String imageKey = String.valueOf(params[0]);
+
outputStream.flush();
 +
outputStream.close();
 +
sDiskLruCache.flush();
 +
editor.commit();
  
        // Check disk cache in background thread
+
// 削除
        Bitmap bitmap = getBitmapFromDiskCache(imageKey);
+
sDiskLruCache.delete();
  
         if (bitmap == null) { // Not found in disk cache
+
public class Streams {
             // Process as normal
+
    public static void copyContent(final InputStream inputStream, final OutputStream outputStream) throws IOException {
            final Bitmap bitmap = decodeSampledBitmapFromResource(
+
         if (inputStream == null || outputStream == null) {
                    getResources(), params[0], 100, 100));
+
             throw new IOException("Unable to copy from or to a null stream.");
 +
        }
 +
        byte[] buffer = new byte[16384];
 +
        int length;
 +
        while ((length = inputStream.read(buffer)) != -1) {
 +
            outputStream.write(buffer, 0, length);
 
         }
 
         }
 
        // Add final bitmap to caches
 
        addBitmapToCache(imageKey, bitmap);
 
 
        return bitmap;
 
 
     }
 
     }
    ...
 
 
}
 
}
 +
</pre>
  
public void addBitmapToCache(String key, Bitmap bitmap) {
+
mopubに上記コードの詳細がある
    // Add to memory cache as before
+
https://github.com/mopub/mopub-android-sdk/blob/master/mopub-sdk/mopub-sdk-base/src/main/java/com/mopub/common/CacheService.java
    if (getBitmapFromMemCache(key) == null) {
+
        mMemoryCache.put(key, bitmap);
+
    }
+
  
    // Also add to disk cache
+
==downloadしたものをcacheする==
    synchronized (mDiskCacheLock) {
+
<pre>
        if (mDiskLruCache != null && mDiskLruCache.get(key) == null) {
+
URL u = new URL(mUrl);
            mDiskLruCache.put(key, bitmap);
+
InputStream is = u.openStream();
        }
+
HttpURLConnection huc = (HttpURLConnection)u.openConnection();
     }
+
if (huc != null) {
 +
    InputStream inputStream = new BufferedInputStream(huc.getInputStream());
 +
     boolean diskPutResult = CacheService.putToDiskCache(mUrl, inputStream);
 
}
 
}
 +
</pre>
  
public Bitmap getBitmapFromDiskCache(String key) {
+
==permission追加==
    synchronized (mDiskCacheLock) {
+
保存場所はconstructのparamで指定するので、適宜記述となる。
        // Wait while disk cache is started from background thread
+
        while (mDiskCacheStarting) {
+
            try {
+
                mDiskCacheLock.wait();
+
            } catch (InterruptedException e) {}
+
        }
+
        if (mDiskLruCache != null) {
+
            return mDiskLruCache.get(key);
+
        }
+
    }
+
    return null;
+
}
+
  
// Creates a unique subdirectory of the designated app cache directory. Tries to use external
+
mopubではcontext.getCacheDir()を使っておりAndroidManifestのpermissionは不要だった。
// but if not mounted, falls back on internal storage.
+
https://github.com/mopub/mopub-android-sdk/blob/master/mopub-sdk/mopub-sdk-base/src/main/java/com/mopub/common/CacheService.java
public static File getDiskCacheDir(Context context, String uniqueName) {
+
    // Check if media is mounted or storage is built-in, if so, try and use external cache dir
+
    // otherwise use internal cache dir
+
    final String cachePath =
+
            Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
+
                    !isExternalStorageRemovable() ? getExternalCacheDir(context).getPath() :
+
                            context.getCacheDir().getPath();
+
  
    return new File(cachePath + File.separator + uniqueName);
+
context.getExternalCacheDir()をもし使う場合はKitKatからpermission不要となったが、それ以前では必要なので以下のように追加する
}
+
<pre>
 +
<uses-permission
 +
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
 +
    android:maxSdkVersion="18" />
 
</pre>
 
</pre>
 +
 +
http://wada811.blogspot.com/2014/09/storage-access-and-permission-in-android.html
 +
 +
https://developer.android.com/training/data-storage/files

2018年11月29日 (木) 17:16時点における最新版

準備

以下追加

  • app/build.gradle
dependencies {
    implementation 'com.jakewharton:disklrucache:2.0.2'
}

公式?

https://github.com/JakeWharton/DiskLruCache

google https://android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/io/DiskLruCache.java

okhttp3 https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/internal/cache/DiskLruCache.java

mopub https://github.com/mopub/mopub-android-sdk/blob/master/mopub-sdk/mopub-sdk-base/src/main/java/com/mopub/common/DiskLruCache.java

準備

key部分のhogehogeはmd5やsha1などでhash化して使うと良い。

android/hash [ショートカット]

使い方サンプル

String UNIQUE_CACHE_NAME = "hogehoge-cache";
int VALUE_COUNT = 1;
int DISK_CACHE_INDEX = 0;
String cachePath = context.getCacheDir().getPath()
File cacheDirectory =  new File(cachePath + File.separator + UNIQUE_CACHE_NAME);
long diskCacheSizeBytes = 30 * 1024 * 1024; // 30 MB
// 初期化
DiskLruCache sDiskLruCache = DiskLruCache.open(
                        cacheDirectory,
                        APP_VERSION,
                        VALUE_COUNT,
                        diskCacheSizeBytes);
// 取得
DiskLruCache.Snapshot snapshot = sDiskLruCache.get("hogehoge");
final InputStream in = snapshot.getInputStream(DISK_CACHE_INDEX);

// 更新
DiskLruCache.Editor editor = sDiskLruCache.edit("hogehoge");
final OutputStream outputStream =
        new BufferedOutputStream(editor.newOutputStream(DISK_CACHE_INDEX));
Streams.copyContent(content, outputStream);
outputStream.flush();
outputStream.close();
sDiskLruCache.flush();
editor.commit();

// 削除
sDiskLruCache.delete();

public class Streams {
    public static void copyContent(final InputStream inputStream, final OutputStream outputStream) throws IOException {
        if (inputStream == null || outputStream == null) {
            throw new IOException("Unable to copy from or to a null stream.");
        }
        byte[] buffer = new byte[16384];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
        }
    }
}

mopubに上記コードの詳細がある https://github.com/mopub/mopub-android-sdk/blob/master/mopub-sdk/mopub-sdk-base/src/main/java/com/mopub/common/CacheService.java

downloadしたものをcacheする

URL u = new URL(mUrl);
InputStream is = u.openStream();
HttpURLConnection huc = (HttpURLConnection)u.openConnection();
if (huc != null) {
    InputStream inputStream = new BufferedInputStream(huc.getInputStream());
    boolean diskPutResult = CacheService.putToDiskCache(mUrl, inputStream);
}

permission追加

保存場所はconstructのparamで指定するので、適宜記述となる。

mopubではcontext.getCacheDir()を使っておりAndroidManifestのpermissionは不要だった。 https://github.com/mopub/mopub-android-sdk/blob/master/mopub-sdk/mopub-sdk-base/src/main/java/com/mopub/common/CacheService.java

context.getExternalCacheDir()をもし使う場合はKitKatからpermission不要となったが、それ以前では必要なので以下のように追加する

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18" />

http://wada811.blogspot.com/2014/09/storage-access-and-permission-in-android.html

https://developer.android.com/training/data-storage/files