问题描述
有时候随机死机凌空启动时我的应用程序,它崩溃的应用程序类和用户将无法打开该应用程序再次直到他们进入设置和明确的应用程序数据。
Sometimes randomly Volley crashes my app upon startup, it crashes in the application class and a user would not be able to open the app again until they go into settings and clear app data
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)
在diskbasedbache尝试分配超过1 GB内存,没有明显的理由
The "diskbasedbache" tries to allocate over 1 gigabyte of memory, for no obvious reason
我将如何使这不会发生?这似乎是一个问题,排球,或者是一个问题,一个自定义的基于磁盘的缓存,但我没有立即看到(从堆栈跟踪)如何清除这一高速缓存或做一个条件检查或处理这个异常
how would I make this not happen? It seems to be an issue with Volley, or maybe an issue with a custom disk based cache but I don't immediately see (from the stack trace) how to 'clear' this cache or do a conditional check or handle this exception
洞察AP preciated
Insight appreciated
推荐答案
在 streamToBytes()
,首先它会在缓存文件长度的新的字节,你的缓存文件是不是应用程序的最大堆大小是否过大?
In the streamToBytes()
, first it will new bytes by the cache file length, does your cache file was too large than application maximum heap size ?
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());
}
如果要清除高速缓存中,你可以保持 DiskBasedCache
的参考,经过明确的时间的来了,使用 ClearCacheRequest
并通过高速缓存实例:
If you want to clear the cache, you could keep the DiskBasedCache
reference, after clear time's came, use ClearCacheRequest
and pass that cache instance in :
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));
这样将清除所有的缓存,所以我建议你仔细地使用它。当然,你可以做条件检查
,只是迭代的 cacheDir 的文件,估计这是太大,然后将其删除。
this way will clear all caches, so I suggest you use it carefully. of course, you can doing conditional check
, just iterating the cacheDir files, estimate which was too large then remove it.
for (File cacheFile : cacheDir.listFiles()) {
if (cacheFile.isFile() && cacheFile.length() > 10000000) cacheFile.delete();
}
抽射被没有设计作为一个大的数据缓存解决方案,这是常见的请求缓存,不随时存储大量的数据。
Volley wasn't design as a big data cache solution, it's common request cache, don't storing large data anytime.
-------------更新于2014年7月17日-------------
------------- Update at 2014-07-17 -------------
其实,清除所有缓存的最终办法,也不是明智的办法,我们应该燮pressing这些大的请求使用高速缓存的时候,我们确信这将是,如果不知道?我们仍然可以决定是否大或不响应数据的大小,然后调用 setShouldCache(假)
来禁用它。
In fact, clear all caches is final way, also isn't wise way, we should suppressing these large request use cache when we sure it would be, and if not sure? we still can determine the response data size whether large or not, then call setShouldCache(false)
to disable it.
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);
...
}
}
这篇关于凌空内存不足的错误,奇怪的分配尝试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!