将任意文件下载到Android和iOS缓存

问题描述 投票:1回答:1

我写了以下方法:

    /**
     * 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方法在调用时总是下载文件)。

但是,我有些怀疑。

  1. 我的第一个问题是关于缓存的工作原理:目前,我正在使用这种方法下载图像和视频以缓存(在聊天应用程序中),前提是我不需要担心何时不使用文件。因为操作系统会自动删除它们,因此更加必要。是这样吗? OS是否有可能在我使用文件时删除文件(例如,将文件存储到缓存后立即删除),或者Android和iOS仅删除较旧的文件?

  2. 我编写了此方法来存储任意文件。我们可以存储在缓存中的文件大小以MB为单位有合理的限制吗?

  3. 最后,我对方法中使用的Util表示怀疑。以前我没有使用过,但是得到的结果很奇怪:我的回调函数执行UI操作,并且经常(但并非总是)出问题了。我通过添加Util解决了所有回调问题,因此Util是解决方案。但为什么?奇怪的事实是callSeriallycallSerially在后台由callSerially实例的ActionListener调用,因此回调已在EDT中调用(根据Util.downloadUrlToFileSystemInBackground)。可以肯定的是,我在不添加addResponseListener(callback)的情况下在回调中测试了ConnectionRequest,并且它返回了javadoc,因此从理论上讲CN.isEdt()不是必需的,但实际上是必需的。我的推理有什么问题?

谢谢您的解释。

codenameone
1个回答
0
投票
  1. 据我所知,缓存目录只是操作系统在需要空间时可以删除的目录。我认为对于活动的前台应用程序,它不会删除它,但是可能会有所不同。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.