【问题标题】:Multiple asynctasks reusing progressbar多个异步任务重用进度条
【发布时间】:2014-05-13 18:46:05
【问题描述】:

我已经非常彻底地完成了我的研究,但没有实际结果,所以我在这里。

我的应用程序中有一个水平进度条,用于指示文件上传的进度。但是,当我上传整个目录时,我试图让它显示当时上传的单个文件的进度。我使用带有 FixedThreadPool(1) 的异步任务。问题是,只有第一个任务会触发进度条。

主要活动中的方法:

uploadExecutor = Executors.newFixedThreadPool(1);
private void upload() throws DropboxException, IOException {
                if(isDir){
                    DataDir dir = new DataDir(file);
                    List<File> files = dir.getFileList();

                    for(File item : files){
                        Upload upload = new Upload(getActivity(), dropbox, "/Apps/Sink/", item, bar);
                        upload.executeOnExecutor(uploadExecutor);
                    }
                }
                else {
                    Upload upload = new Upload(getActivity(), dropbox, "/Apps/Sink/", file, bar);
                    upload.executeOnExecutor(uploadExecutor);
                }
            }

Upload 是一个实现 AsyncTask 并处理文件上传的类。

创建时,类的实例将条形设置为可见,在 OnPostExecute() 中将其设置为不可见


编辑

添加上传类。

 public Upload(Context context, DropboxAPI<?> api, String dropboxPath,
                  File file, ProgressBar mBar) {

    this.mBar = mBar;
    mBar.setProgress(0);
    mBar.setVisibility(View.VISIBLE)

@Override protected Boolean doInBackground(Void... params){
    try {
        // By creating a request, we get a handle to the putFile operation,
        // so we can cancel it later if we want to
        FileInputStream fis = new FileInputStream(mFile);
        String path = mPath + mFile.getName();
        mRequest = mApi.putFileOverwriteRequest(path, fis, mFile.length(),
                new ProgressListener() {
                    @Override
                    public long progressInterval() {
                        // Update the progress bar every half-second or so
                        return 500;
                    }

                    @Override
                    public void onProgress(long bytes, long total) {
                        publishProgress(bytes);
                    }
                });

        if (mRequest != null) {
            mRequest.upload();
            return true;
        }


@Override
protected void onProgressUpdate(Long... progress) {
    int percent = (int)(100.0*(double)progress[0]/mFileLen + 0.5);
    //mDialog.setProgress(percent);
    mBar.setProgress(percent);
}

@Override
protected void onPostExecute(Boolean result) {
    if (result) {
        showToast("File successfully uploaded");
    } else {
        showToast(mErrorMsg);
    }
    mBar.setVisibility(View.INVISIBLE);
}

编辑

我通过将 for 循环移到上传类中解决了这个问题。 非常相似的方法HERE

【问题讨论】:

    标签: android android-asynctask


    【解决方案1】:

    在您的 Upload 类中,您可以实现 AsynkTak 检查进度状态更改的方法

    protected void onProgressUpdate(Integer...progress) { /你的代码/ }

    http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress...)

    【讨论】:

    • 谢谢,我当然已经这样做了。问题是,它仅在第一个文件上传时才显示栏。帖子编辑
    【解决方案2】:

    您遇到的问题是您为每个文件初始化一个 AsyncTask 并为每个文件提供对同一个 ProgressBar 的引用。

    发生的情况是,您遍历文件并初始化 AsyncTasks。现在,如果第一个任务完成,该栏将设置为不可见。以下任务无法使用您当前的设置再次将其设置为可见。

    你可以尝试在 AsyncTask 的onPostExecute() 中设置 bar 可见,因为这个会在 doInBackground() 启动之前被调用。或者你可以在 doInBackground() 的开头触发 onProgreesUpdate() 来使它在那里可见。

    【讨论】:

    • 感谢您的回复。我都试过了,但总是以异常结束。 “ViewRootImpl$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图。”
    • 你能显示你试过的代码吗?不要直接在 doInBackground() 中更新视图。
    • 我只是将 SetVisibility 移动到 OnProgressUpdate 并在 doInBackground 的开头调用了 OnProgressUpdate。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    相关资源
    最近更新 更多