Hello StackOverflowers,
我开发了使用Volley与REST Web API进行通信的项目。我使用复杂的图像加载过程。
我想加载用户的脸谱资料图片,有时我想首先获取存储缓存图片,有时我希望它始终来自互联网。
问题是来自facebook的图片网址总是一样的。这就是我基本检查图像文件大小是否与缓存文件大小不同的原因。
我正在使用Volley的ImageLoader和它的缓存实现。然后我发现用ImageLoader做它很复杂,所以我选择使用Picasso但它没有显示缓存的图像。
我知道要使Picasso缓存工作,我需要一个自定义的“Downloader”,我知道我可以用OkHttp做到这一点,但我的项目已经在使用Volley进行所有REST调用。
那么可以使用Volley作为Picasso及其图像缓存结构的下载器吗?
以下是我设法解决第一个问题的方法,现在只有缓存流程才出现问题:
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");
}
}
}
}