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 <example@example.com> Co-authored-by: M M Arif <mmarif@swatian.com> Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/345 Reviewed-by: 6543 <6543@noreply.gitea.io> Reviewed-by: M M Arif <mmarif@swatian.com>
This commit is contained in:
		| @@ -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) { | ||||
|   | ||||
							
								
								
									
										203
									
								
								app/src/main/java/org/mian/gitnex/helpers/PicassoCache.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								app/src/main/java/org/mian/gitnex/helpers/PicassoCache.java
									
									
									
									
									
										Normal file
									
								
							| @@ -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<String, String> 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<len; i++) { | ||||
|  | ||||
| 				if(key.charAt(i) != keyPrefix.charAt(i)) { | ||||
|  | ||||
| 					match = false; | ||||
| 					break; | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
|  | ||||
| 			if(match) { | ||||
|  | ||||
| 				//noinspection ResultOfMethodCallIgnored | ||||
| 				new File(cachePath, cacheMap.get(key)).delete(); | ||||
| 				cacheMap.remove(key); | ||||
|  | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	private String generateRandomFilename() { | ||||
|  | ||||
| 		return UUID.randomUUID().toString(); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	private void saveCacheMap(Map<String, String> 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<String, String> loadCacheMap() throws IOException, ClassNotFoundException { | ||||
|  | ||||
| 		ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File(cachePath, CACHE_MAP_FILE))); | ||||
|  | ||||
| 		Map<String, String> map = (HashMap<String, String>) objectInputStream.readObject(); | ||||
| 		objectInputStream.close(); | ||||
|  | ||||
| 		return map; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	private boolean cacheMapExists(File cachePath) { | ||||
|  | ||||
| 		return new File(cachePath, CACHE_MAP_FILE).exists(); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user