【问题标题】:Best way to download files synchronously (downloadManager)同步下载文件的最佳方式(downloadManager)
【发布时间】:2016-03-06 18:01:38
【问题描述】:

我尝试在我的主线程中同步下载一些文件。 此外,我创建了一个递归方法,该方法在每次接收回调时调用自身(使用progressdialog 增量),但是在200/250 次递归调用之后,我遇到了堆栈溢出错误。这似乎不是最好的做法。 之后,我尝试了一个简单的 for 循环,但每个循环之间的下载都没有完成,所以 unregisterReceiver 没有被调用,这会造成泄漏。

这是我的循环代码:

    private void loadMediaFiles(final ArrayList<MediaAPIModel> mediaAPIModels, final ProgressDialog progressDialog) {
    for(int i = 0; i < mediaAPIModels.size(); i++) {
        if (mediaAPIModels.get(i).getUrl() != null) {
            if (!FileManager.getInstance().getFileFromLocal(context, mediaAPIModels.get(i).getUrl(), false)) {
                String name = mediaAPIModels.get(i).getUrl().substring(mediaAPIModels.get(i).getUrl().lastIndexOf("/") + 1); //on s?pare le nom du fichier du reste de l'url
                Log.d(TAG, CallAPI.mBaseUrl + mediaAPIModels.get(i).getUrl());
                DownloadManager.Request request = new DownloadManager.Request(Uri.parse(CallAPI.mBaseUrl + mediaAPIModels.get(i).getUrl()));
                request.setDescription(context.getResources().getString(R.string.downloading) + " name");
                request.setTitle(context.getResources().getString(R.string.app_name));
                request.setMimeType(name.substring(name.lastIndexOf(".")));
                // in order for this if to run, you must use the android 3.2 to compile your app
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                    request.allowScanningByMediaScanner();
                    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                }
                request.setDestinationInExternalPublicDir("test" + File.separatorChar + "doc", name);
                DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
                manager.enqueue(request);

                context.registerReceiver(new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        context.unregisterReceiver(this);
                        progressDialog.setProgress(progressDialog.getProgress() + 1);
                    }
                }, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
            } else {
                Log.d(TAG, "doc already exists");
                progressDialog.setProgress(progressDialog.getProgress() + 1);
            }
        } else {
            Log.d(TAG, "finish");
            progressDialog.setProgress(progressDialog.getProgress() + 1);
        }
    }
    if (progressDialog.isShowing())
        progressDialog.dismiss();
    startProcess();
}

对不起,如果我的英语不好^^'

【问题讨论】:

  • 你不应该在主线程上下载文件,为什么不使用异步任务

标签: android recursion stack-overflow synchronous android-download-manager


【解决方案1】:

下载完成后,您无需取消注册 BroadcastReceiver。它只需要在应用程序从视图中删除之前进行清理。因此,最好的做法是在 Activity 的 onPause() 方法中取消注册接收器,以便在应用移至后台或完全完成时简单地清理它。

至于您在下载过程中的进度更新,DownloadManager 会自动显示下载进度。您只需致电request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);

如果您想实现自己的进度 UI,您可以查询 DownloadManager 存储在 DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR 中的下载的内部字节数,然后当您在 BroadcastReceiver 中收到通知时取消您的 UI 元素DownloadManager.ACTION_DOWNLOAD_COMPLETE

如您所见,有很多方法可以做您想做的事情。听起来您需要阅读更多有关 DownloadManager 文档的内容,以便您可以充分利用该类提供的便利。

【讨论】:

    猜你喜欢
    • 2019-03-05
    • 2021-08-15
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 2018-07-24
    相关资源
    最近更新 更多