第一个问题是我每次在下载之前都会创建新的 httpclient,因此每次都会创建 HttpCacheStorage 的新实例,这就是文件具有不同名称的原因。
其次,默认的 HttpCacheStorage 将下载数据的信息存储在 LinkedHashMap 中,因此每次新启动应用程序后,cacheStorage 都不知道上次启动时缓存的数据。
解决方案是创建自己的 Http 缓存存储,它将缓存的数据保存到文件系统,并在可以从缓存中获取响应时从文件中获取数据。
我刚刚向 CachingHttpClientBuilder 添加了一行 - setHttpCacheStorage
CachingHttpClientBuilder.create()
.setCacheConfig(cacheConfig)
.setHttpCacheStorage(new ImagesCacheStorage(cacheConfig, cacheDir))
.setDefaultRequestConfig(config)
.build();
并创建了新类 FileCacheStorage
import myapp.org.apache.http.client.cache.HttpCacheEntry;
import myapp.org.apache.http.client.cache.HttpCacheUpdateCallback;
import myapp.org.apache.http.impl.client.cache.CacheConfig;
import myapp.org.apache.http.impl.client.cache.ManagedHttpCacheStorage;
public class FileCacheStorage extends ManagedHttpCacheStorage {
private File mCacheDir;
public FileCacheStorage(final CacheConfig config, File cacheDir) {
super(config);
mCacheDir = cacheDir;
}
@Override
public HttpCacheEntry getEntry(final String url) throws IOException {
HttpCacheEntry entry = super.getEntry(url);
if (entry == null) {
entry = loadCacheEnrty(url);
}
return entry;
}
@Override
public void putEntry(final String url, final HttpCacheEntry entry) throws IOException {
super.putEntry(url, entry);
saveCacheEntry(url, entry);
}
@Override
public void removeEntry(final String url) throws IOException {
super.removeEntry(url);
File cache = getCacheFile(url);
if (cache != null && cache.exists()) {
cache.delete();
}
}
@Override
public void updateEntry(
final String url,
final HttpCacheUpdateCallback callback) throws IOException {
super.updateEntry(url, callback);
HttpCacheEntry entry = loadCacheEnrty(url);
if (entry != null) {
callback.update(entry);
}
}
private void saveCacheEntry(String url, HttpCacheEntry entry) {
ObjectOutputStream stream = null;
try {
File cache = getCacheFile(url);
stream = new ObjectOutputStream(new FileOutputStream(cache));
stream.writeObject(entry);
stream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private HttpCacheEntry loadCacheEnrty(String url) {
HttpCacheEntry entry = null;
File cache = getCacheFile(url);
if (cache != null && cache.exists()) {
synchronized (this) {
ObjectInputStream stream = null;
try {
stream = new ObjectInputStream(new FileInputStream(cache));
entry = (HttpCacheEntry) stream.readObject();
stream.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return entry;
}
private File getCacheFile(String url) {
return new File(mCacheDir, MD5.getHash(url));
}
}
正如您所看到的,Apache 类的包名称带有前缀 myapp。当我尝试使用原始 jar 文件时出现错误,我认为这是因为 Android 中已经存在许多类。因此,我组合了 apache 中的几个 jar 文件,并用它们制作了一个带有该前缀的 jar。如果有人有更好的解决方案请告诉我。
希望它能帮助某人。