如何使用界面更新异步任务中的进度条

Posted

技术标签:

【中文标题】如何使用界面更新异步任务中的进度条【英文标题】:How to update the Progress Bar in Async Task with interface 【发布时间】:2017-11-26 16:18:16 【问题描述】:

我创建了一个应用程序,其中我使用了 Fragment 类和另一个 Async 类来下载两个不同的类现在我必须显示进度条水平更新进度条在 onProgressUpdate 中发生了多少下载。但是 onProgressUpdate 回调不起作用的接口,它没有更新 ProgressBar。

FragmentA.class

private void downloadAndUnzipContent(String url)
    progressBar.setVisibility(View.VISIBLE);
    progressBar.setProgress(0);
    DownloadFileAsync download = new DownloadFileAsync(path+"content.zip", mContext,
            new DownloadFileAsync.PostDownload()
        @Override
        public void downloadDone(File file) 
            Log.i(TAG, "file download completed");
        
    , new DownloadFileAsync.ProgressUpdate() 

        @Override
        public void ProgressUpdate(int progress) 
            progressBar.setProgress(progress);
        

    );
    download.execute(url);

在我下载文件的 DownloadFileAsync.class 中:

public class DownloadFileAsync extends AsyncTask<String, Integer, String> 

private static final String TAG = "DOWNLOADFILE";

public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private PostDownload callback;
private ProgressUpdate callProgress;
private Context context;
private FileDescriptor fd;
private File file;
private String downloadLocation;

public DownloadFileAsync(String downloadLocation, Context context, PostDownload callback, ProgressUpdate callProgress) 
    this.context = context;
    this.callback = callback;
    this.callProgress = callProgress;
    this.downloadLocation = downloadLocation;


@Override
protected void onPreExecute() 
    super.onPreExecute();


@Override
protected String doInBackground(String... aurl) 
    int count;

    try 
        URL url = new URL(aurl[0]);
        URLConnection connection = url.openConnection();
        connection.connect();

        int lenghtOfFile = connection.getContentLength();
        Log.d(TAG, "Length of the file: " + lenghtOfFile);

        InputStream input = new BufferedInputStream(url.openStream());
        file = new File(downloadLocation);
        FileOutputStream output = new FileOutputStream(file); //context.openFileOutput("content.zip", Context.MODE_PRIVATE);
        Log.d(TAG, "file saved at " + file.getAbsolutePath());
        fd = output.getFD();

        byte data[] = new byte[1024];
        long total = 0;
        while ((count = input.read(data)) != -1) 
            total += count;
            publishProgress((int) ((total * 100) / lenghtOfFile));
            output.write(data, 0, count);
        

        output.flush();
        output.close();
        input.close();
     catch (Exception e) 
    
    return null;



protected void onProgressUpdate(Integer... progress) 
    //Log.d(TAG,progress[0]);
    if(callProgress != null)
        callProgress.ProgressUpdate(progress[0]);


@Override
protected void onPostExecute(String unused) 
    //progressBar.setVisibility(View.GONE);
    if (callback != null) callback.downloadDone(file);


public  interface PostDownload 
    void downloadDone(File fd);


public interface ProgressUpdate 
    void ProgressUpdate(int progress);


我的代码有错误吗?

【问题讨论】:

***.com/questions/3028306/… 不需要接口,直接从异步任务类中完成 你只需要通过一个活动来保存片段的Ui元素的引用,你可以直接从异步类的onProgressUpdate更新进度条,因为你有上下文变量 【参考方案1】:

您的代码没有问题。 请调试检查

 int lenghtOfFile = connection.getContentLength();

“lenghtOfFile”是正确的。 并非所有服务器都返回 ContentLength。 有时是 -1。

【讨论】:

【参考方案2】:

您不能在 UI 线程之外修改 UI。快速修复可能是:

    yourFragment.getActivity().runOnUiThread(new Runnable()
    
        @Override
        public void run()
        
            progressBar.setProgress(progress);
        
    );

【讨论】:

以上是关于如何使用界面更新异步任务中的进度条的主要内容,如果未能解决你的问题,请参考以下文章

如何在异步任务中更新进度栏

我如何在我的异步任务类中使用圆形旋转进度条

android 如何实现弹出一个进度条后,再弹出一个倒计时的界面。

如何在Android开发中用AsyncTask异步更新UI界面

如何在service中同步更新通知activity中的进度条

android:异步任务asyncTask介绍及异步任务下载图片(带进度条)