CQM*_*CQM 17 android out-of-memory android-volley diskcache
有时随机Volley在启动时崩溃我的应用程序,它在应用程序类中崩溃,用户无法再次打开应用程序,直到他们进入设置并清除应用程序数据
java.lang.OutOfMemoryError
at com.android.volley.toolbox.DiskBasedCache.streamToBytes(DiskBasedCache.java:316)
at com.android.volley.toolbox.DiskBasedCache.readString(DiskBasedCache.java:526)
at com.android.volley.toolbox.DiskBasedCache.readStringStringMap(DiskBasedCache.java:549)
at com.android.volley.toolbox.DiskBasedCache$CacheHeader.readHeader(DiskBasedCache.java:392)
at com.android.volley.toolbox.DiskBasedCache.initialize(DiskBasedCache.java:155)
at com.android.volley.CacheDispatcher.run(CacheDispatcher.java:84)
Run Code Online (Sandbox Code Playgroud)
"diskbasedbache"尝试分配超过1 GB的内存,没有明显的原因
我怎么能让这件事不发生?这似乎是Volley的问题,或者可能是基于自定义磁盘的缓存的问题,但我没有立即看到(从堆栈跟踪)如何"清除"此缓存或执行条件检查或处理此异常
洞察力赞赏
Vin*_*ing 15
在streamToBytes(),首先它会在缓存文件长度的字节新,贵缓存文件比应用程序的最大堆大小是否过大?
private static byte[] streamToBytes(InputStream in, int length) throws IOException {
byte[] bytes = new byte[length];
...
}
public synchronized Entry get(String key) {
CacheHeader entry = mEntries.get(key);
File file = getFileForKey(key);
byte[] data = streamToBytes(..., file.length());
}
Run Code Online (Sandbox Code Playgroud)
如果要清除缓存,可以DiskBasedCache在清除时间之后保留引用,使用ClearCacheRequest并传递该缓存实例:
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
DiskBasedCache cache = new DiskBasedCache(cacheDir);
RequestQueue queue = new RequestQueue(cache, network);
queue.start();
// clear all volley caches.
queue.add(new ClearCacheRequest(cache, null));
Run Code Online (Sandbox Code Playgroud)
这种方式将清除所有缓存,所以我建议你仔细使用它.当然,你可以做conditional check,只是迭代cacheDir文件,估计哪个太大然后删除它.
for (File cacheFile : cacheDir.listFiles()) {
if (cacheFile.isFile() && cacheFile.length() > 10000000) cacheFile.delete();
}
Run Code Online (Sandbox Code Playgroud)
Volley并不是一个大数据缓存解决方案,它是常见的请求缓存,不会随时存储大数据.
-------------更新于2014-07-17 -------------
事实上,清除所有缓存是最后的方式,也是不明智的方式,我们应该在我们确定它时会抑制这些大量请求使用缓存,如果不确定的话?我们仍然可以确定响应数据大小是否大,然后调用setShouldCache(false)禁用它.
public class TheRequest extends Request {
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
// if response data was too large, disable caching is still time.
if (response.data.length > 10000) setShouldCache(false);
...
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11377 次 |
| 最近记录: |