From 9b3a9aada71f1d89b6ec62e70a43ad0199f48c55 Mon Sep 17 00:00:00 2001 From: anonTree1417 Date: Fri, 3 Apr 2020 17:02:46 +0000 Subject: [PATCH] Adding caching to picasso service (#345) Merge remote-tracking branch 'remotes/main/master' into picasso-img-cache Some improvements including size management and easy customization. Improvements to picasso cache Making PicassoCache public Moving PicassoCache to helpers/ Merge branch 'master' into picasso-img-cache Adding options for customisation. (Hopefully) final bug fixes. Additional fixes. Hotfix. Prevent NullPointerException. Formatting stuff. Removing unnecessary permission. Adding permission. Adding PicassoCache. Using max-stale now. Adding caching to picasso service Co-authored-by: anonTree1417 Co-authored-by: M M Arif Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/345 Reviewed-by: 6543 <6543@noreply.gitea.io> Reviewed-by: M M Arif --- .../mian/gitnex/clients/PicassoService.java | 9 +- .../org/mian/gitnex/helpers/PicassoCache.java | 203 ++++++++++++++++++ 2 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/org/mian/gitnex/helpers/PicassoCache.java diff --git a/app/src/main/java/org/mian/gitnex/clients/PicassoService.java b/app/src/main/java/org/mian/gitnex/clients/PicassoService.java index e759d773..9ad334e6 100644 --- a/app/src/main/java/org/mian/gitnex/clients/PicassoService.java +++ b/app/src/main/java/org/mian/gitnex/clients/PicassoService.java @@ -4,9 +4,10 @@ import android.content.Context; import android.util.Log; import com.squareup.picasso.OkHttp3Downloader; import com.squareup.picasso.Picasso; +import org.mian.gitnex.helpers.PicassoCache; import org.mian.gitnex.helpers.ssl.MemorizingTrustManager; +import java.io.File; import java.security.SecureRandom; -import java.util.Objects; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; @@ -44,7 +45,11 @@ public class PicassoService { }); - picasso = builder.build(); + File cachePath = new File(context.getCacheDir() + "/picasso_cache/"); + //noinspection ResultOfMethodCallIgnored + cachePath.mkdirs(); + + picasso = builder.memoryCache(new PicassoCache(cachePath)).build(); } catch(Exception e) { diff --git a/app/src/main/java/org/mian/gitnex/helpers/PicassoCache.java b/app/src/main/java/org/mian/gitnex/helpers/PicassoCache.java new file mode 100644 index 00000000..0fd5ef26 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/PicassoCache.java @@ -0,0 +1,203 @@ +package org.mian.gitnex.helpers; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Log; +import com.squareup.picasso.Cache; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Author anonTree1417 + */ + +public class PicassoCache implements Cache { + + private String TAG = "PicassoCache"; + + private static final Bitmap.CompressFormat COMPRESS_FORMAT = Bitmap.CompressFormat.PNG; + private static final int COMPRESSION_QUALITY = 0; // 0 = high compression (low file size) | 100 = no compression + + private static final String CACHE_MAP_FILE = "cacheMap"; + private static final int CACHE_SIZE = 25 * 1024 * 1024; // Cache can hold twenty-five megabytes + + private File cachePath; + private HashMap cacheMap; + + public PicassoCache(File cachePath) throws IOException, ClassNotFoundException { + + this.cachePath = cachePath; + cacheMap = new HashMap<>(); + + if(cacheMapExists(cachePath)) { + + cacheMap.putAll(loadCacheMap()); + + } + + } + + @Override + public Bitmap get(String key) { + + try { + + if(cacheMap.containsKey(key)) { + + FileInputStream fileInputStream = new FileInputStream(new File(cachePath, cacheMap.get(key))); + + Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream); + fileInputStream.close(); + + return bitmap; + + } + + } + catch(IOException e) { + + Log.e(TAG, e.toString()); + + } + + return null; + + } + + @Override + public void set(String key, Bitmap bitmap) { + + try { + + String uuid = generateRandomFilename(); + File file = new File(cachePath, uuid); + + FileOutputStream fileOutputStream = new FileOutputStream(file, false); + bitmap.compress(COMPRESS_FORMAT, COMPRESSION_QUALITY, fileOutputStream); + + fileOutputStream.flush(); + fileOutputStream.close(); + + cacheMap.put(key, uuid); + saveCacheMap(cacheMap); + + } + catch(IOException e) { + + Log.e(TAG, e.toString()); + + } + + } + + @Override + public int size() { + + int currentSize = 0; + + for(String key : cacheMap.keySet()) { + + currentSize += new File(cachePath, cacheMap.get(key)).length(); + + } + + return currentSize; + + } + + @Override + public int maxSize() { + + return CACHE_SIZE; + + } + + @Override + public void clear() { + + File[] files = cachePath.listFiles(); + + if(files != null) { + + for(File file : files) { + + //noinspection ResultOfMethodCallIgnored + file.delete(); + + } + + } + + } + + @Override + public void clearKeyUri(String keyPrefix) { + + for(String key : cacheMap.keySet()) { + + int len = Math.min(keyPrefix.length(), key.length()); + boolean match = true; + + for(int i=0; i cacheMap) throws IOException { + + ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(new File(cachePath, CACHE_MAP_FILE), false)); + + objectOutputStream.writeObject(cacheMap); + objectOutputStream.flush(); + objectOutputStream.close(); + + } + + private Map loadCacheMap() throws IOException, ClassNotFoundException { + + ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File(cachePath, CACHE_MAP_FILE))); + + Map map = (HashMap) objectInputStream.readObject(); + objectInputStream.close(); + + return map; + + } + + private boolean cacheMapExists(File cachePath) { + + return new File(cachePath, CACHE_MAP_FILE).exists(); + + } + +}