Hello StackOverflowers,
I developed project which is using Volley for communicating with REST web API. I use complex image loading process.
I want to load user's facebook profile picture and sometimes I want it first to get storage cached image and sometimes I want it to be always from internet.
The problem is that image url from facebook is always the same. This is why I made a basic check if image file size differs from the cached one.
I was using Volley's ImageLoader and it's cache implementation. Then I found it complex to do it with ImageLoader so I choose to use Picasso but it doesn't show cached image.
I know that for Picasso cache to work I need a custom "Downloader" and I know I can do it with OkHttp but my project is already using Volley for all REST calls.
So is it possible to use Volley as downloader for Picasso and its image cache structure?
Here is how I managed to fix the first issue and only the caching flow is the problem now:
public class PerfectImageLoader {
private static final String TAG = PerfectImageLoader.class.getSimpleName();
private Context mContext;
private SharedPreferences mSharedPreferences;
public PerfectImageLoader(Context context)
throws NullPointerException {
if (context == null) {
throw new NullPointerException("Context cannot be null");
}
mContext = context;
mSharedPreferences = context.getSharedPreferences(
context.getPackageName(), Context.MODE_PRIVATE);
}
public void getImage(final String imageUrl, final ImageView imageView) {
getImage(imageUrl, imageView, false);
}
public void getImage(final String imageUrl, final ImageView imageView,
final boolean isAwlaysFromInternet)
throws NullPointerException {
if (imageView == null) {
throw new NullPointerException("OnImageFromCacheListener cannot be null");
}
if (TextUtils.isEmpty(imageUrl)) {
throw new NullPointerException("image url cannot be null");
}
if (!isAwlaysFromInternet) {
loadCachedImage(imageUrl, imageView, null);
}
calculateFileSize(imageUrl, new OnFileSizeCheck() {
@Override
public void ready(final int networkFileSize) {
int cachedImageSize = mSharedPreferences
.getInt(imageUrl, 0);
TLog.v(TAG, "networkFileSize:" + networkFileSize);
TLog.v(TAG, "cachedImageSize:" + cachedImageSize);
if (cachedImageSize != networkFileSize || cachedImageSize == 0) {
TLog.v(TAG, "cachedImageSize != networkFileSize");
final Callback callback = new Callback() {
@Override
public void onSuccess() {
TLog.v(TAG, "downloaded");
mSharedPreferences.edit()
.putInt(imageUrl, networkFileSize).apply();
}
@Override
public void onError() {
TLog.v(TAG, "error");
if (isAwlaysFromInternet) {
mSharedPreferences.edit()
.remove(imageUrl).apply();
imageView.setImageBitmap(null);
}
}
};
if (isAwlaysFromInternet) {
TLog.v(TAG, "MemoryPolicy.NO_CACHE");
Picasso.with(mContext).load(imageUrl).memoryPolicy(MemoryPolicy.NO_CACHE)
.into(imageView, callback);
} else {
Picasso.with(mContext).load(imageUrl).into(imageView, callback);
}
} else {
TLog.v(TAG, "cachedImageSize == networkFileSize");
loadCachedImage(imageUrl, imageView, new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError() {
Picasso.with(mContext).load(imageUrl).into(imageView);
}
});
}
}
});
}
private void loadCachedImage(final String imageUrl, final ImageView imageView,
Callback callback) {
if (callback != null) {
Picasso.with(mContext)
.load(imageUrl)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(imageView, callback);
} else {
Picasso.with(mContext)
.load(imageUrl)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(imageView);
}
}
public static void calculateFileSize(String url, final OnFileSizeCheck fileSizeCallbacks)
throws NullPointerException {
if (fileSizeCallbacks != null && !TextUtils.isEmpty(url)) {
new AsyncTask<String, Void, Integer>() {
@Override
protected Integer doInBackground(String... params) {
Integer fileSize = null;
try {
URL urlObj = new URL(params[0]);
URLConnection urlConnection = urlObj.openConnection();
urlConnection.connect();
fileSize = urlConnection.getContentLength();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return fileSize;
}
@Override
protected void onPostExecute(Integer fileSize) {
super.onPostExecute(fileSize);
if (fileSizeCallbacks != null) {
fileSizeCallbacks.ready(fileSize);
}
}
}.execute(url);
} else {
if (fileSizeCallbacks == null) {
throw new NullPointerException("file size callbacks parameter is null");
}
if (url == null) {
throw new NullPointerException("url parameter is null");
} else if (TextUtils.isEmpty(url)) {
throw new NullPointerException("url parameter is empty");
}
}
}
}