我写了以下方法:
/**
* Downloads an arbitrary file to the cache asynchronously, if the current
* platform has a cache path, or to the app home; if the file was previously
* downloaded and if it's still available on the cache, it calls the
* onSuccess callback immediatly.More info:
* https://www.codenameone.com/blog/cache-sorted-properties-preferences-listener.html
*
* @param url The URL to download.
* @param extension you can leave it empty or null, however iOS cannot play
* videos without extension (https://stackoverflow.com/q/49919858)
* @param onSuccess Callback invoked on successful completion (on EDT by
* callSerially).
* @param onFail Callback invoked on failure (on EDT by callSerially).
*/
public static void downloadFileToCache(String url, String extension, SuccessCallback<String> onSuccess, Runnable onFail) {
FileSystemStorage fs = FileSystemStorage.getInstance();
if (extension == null) {
extension = "";
}
if (extension.startsWith(".")) {
extension = extension.substring(1);
}
String name = "cache_" + HashUtilities.sha256hash(url);
if (!extension.isEmpty()) {
name += "." + extension;
}
String filePath;
if (fs.hasCachesDir()) {
// this is supported by Android, iPhone and Javascript
filePath = fs.getCachesDir() + fs.getFileSystemSeparator() + name;
} else {
// The current platform doesn't have a cache path (for example the Simulator)
String homePath = fs.getAppHomePath();
filePath = homePath + fs.getFileSystemSeparator() + name;
}
// Was the file previously downloaded?
if (fs.exists(filePath)) {
CN.callSerially(() -> onSuccess.onSucess(filePath));
} else {
Util.downloadUrlToFileSystemInBackground(url, filePath, (evt) -> {
if (fs.exists(filePath)) {
CN.callSerially(() -> onSuccess.onSucess(filePath));
} else {
CN.callSerially(onFail);
}
});
}
}
有效。它与Util
类提供的某些方法类似,但有两个主要区别:首先是Util
类提供仅用于将图像下载到缓存的方法,而我想下载任意文件;第二个是我可以假设相同的url总是返回相同的文件,因此如果它仍在缓存中,则不需要再次下载它(而Util
方法在调用时总是下载文件)。
但是,我有些怀疑。
我的第一个问题是关于缓存的工作原理:目前,我正在使用这种方法下载图像和视频以缓存(在聊天应用程序中),前提是我不需要担心何时不使用文件。因为操作系统会自动删除它们,因此更加必要。是这样吗? OS是否有可能在我使用文件时删除文件(例如,将文件存储到缓存后立即删除),或者Android和iOS仅删除较旧的文件?
我编写了此方法来存储任意文件。我们可以存储在缓存中的文件大小以MB为单位有合理的限制吗?
最后,我对方法中使用的Util
表示怀疑。以前我没有使用过,但是得到的结果很奇怪:我的回调函数执行UI操作,并且经常(但并非总是)出问题了。我通过添加Util
解决了所有回调问题,因此Util
是解决方案。但为什么?奇怪的事实是callSerially
的callSerially
在后台由callSerially
实例的ActionListener
调用,因此回调已在EDT中调用(根据Util.downloadUrlToFileSystemInBackground
)。可以肯定的是,我在不添加addResponseListener(callback)
的情况下在回调中测试了ConnectionRequest
,并且它返回了javadoc,因此从理论上讲CN.isEdt()
不是必需的,但实际上是必需的。我的推理有什么问题?
谢谢您的解释。
据我所知,缓存目录只是操作系统在需要空间时可以删除的目录。我认为对于活动的前台应用程序,它不会删除它,但是可能会有所不同。