java - 监控 BufferedInputStream 下载进度

标签 java android android-asynctask progressdialog bufferedinputstream

我正尝试在 Android 上使用 AsyncTask 下载文件。我想显示一个 ProgressDialog,它应该有一个进度条来显示下载状态。为此,我使用了 onProgressUpdate() 函数,并在我的 doInBackground() 函数中实现了对 publishProgress() 的调用。但是,进度对话框仅在下载文件后 弹出。我的代码:

protected Long doInBackground(URL...urls) {
    for (int i = 0; i < urls.length; i++) {
        url = urls[i];
        try {
            URLConnection conn = url.openConnection();
            conn.connect();
            totalSize = conn.getContentLength();

            BufferedInputStream bis = new BufferedInputStream(url.openStream());
            FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/forvo_temp.mp3");
            BufferedOutputStream bos = new BufferedOutputStream(fos,1024);
            byte [] data = new byte[1024];

            int x=0; int c=0;
            while((x=bis.read(data,0,1024))>=0){
                bos.write(data,0,x);
                c += 1024;
                publishProgress(c);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return 0L; // Don't know what to do with this
}

protected void onProgressUpdate(Integer...args) {
    pd = ProgressDialog.show(context, "Downloading...", "Downloading...", true, false);
    pd.setProgress(args[0] / totalSize);
}

我想当我调用 new BufferedInputStream(url.openStream()) 时,整个文件都被下载了。如何监控下载进度?

最佳答案

用您自己的 InputStream 包装 URL 输入流,它只读取字节并“监控”状态,例如发送通知。

很简单:InputStream是一个抽象类,只有一个抽象方法:

public abstract int read() throws IOException;

在您的情况下,它应该从它包装的流中读取字节。

public class NotifcationInputStream extends InputStream {
    private InputStream in;
    private int count;
    private Collection<ByteListener> listeners = new ArrayList<ByteListener>();

    NotificationInputStream(InputStream in) {
         this.in = in;
    }

    public int read() throws IOException {
        int b = in.read(); 
        byteReceived(b);
        return b;
    }

    public void addListener(ByteListener listener) {
        listeners.add(listener);
    }

    private void byteReceived(int b) {
        for (ByteListener l : listeners) {
             l.byteReceived(b, ++count);
        }
    }
}


public interface ByteListener extends EventListener {
    public void byteReceived(int b, int count);
}

这里的问题是如何显示进程条:你必须知道总字节数。如果您的资源是静态的,您可以从 HTTP header content-length 中获取它。否则,您需要适当的服务器支持或启发式方法。

关于java - 监控 BufferedInputStream 下载进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16518274/

相关文章:

java - EMF 产生 Swing 应用

android - 从 BroadcastReceiver/AsyncTask 连接到 Google Drive

java - 派生的 TimerTask 类中出现错误 : `Can' t create handler inside thread that has not called Looper. 准备()`

android - AsyncTask<String, Void, Void> 是如何工作的?

android - 如何完全杀死/删除/删除/停止 AsyncTask

java - Android ListView 未更新

java - 推送完后如何获取 child 的数据?

java - 我如何结合搜索 ListView 和ListView.OnItemClickListener

Android Presentation 类 - 如何动态更改 Presentation View

android - 发送请求时删除的端口