【问题标题】:How to implement file upload progress bar in android如何在android中实现文件上传进度条
【发布时间】:2011-10-18 23:04:48
【问题描述】:

我正在通过org.apache.http.client.HttpClient 在android 中上传文件,我需要实现进度条。是否可以从以下方面获取进度?

HttpPost httppost = new HttpPost("some path");
HttpClient httpclient = new DefaultHttpClient();
try {
File file = new File("file path");
InputStream in = new BufferedInputStream(new FileInputStream(file));
byte[] bArray = new byte[(int) file.length()];
in.read(bArray);
String entity = Base64.encodeToString(bArray, Base64.DEFAULT);
httppost.setEntity(new StringEntity(entity));
HttpResponse response = httpclient.execute(httppost);
}

如果没有,请显示另一种方法。谢谢

【问题讨论】:

标签: android


【解决方案1】:

您要做的是创建一个 AsyncTask 来为您处理此问题,覆盖 onProgressUpdate 方法。

这是我在另一个应用程序中使用HttpURLConnection 测试的一个精简版本。可能会有一些小的冗余,我认为HttpURLConnection 可能通常不受欢迎,但这应该可行。只需通过调用new FileUploadTask().execute() 在您正在使用的任何Activity 类中使​​用这个类(在本例中,我将其称为TheActivity)。当然,您可能需要对其进行调整以适应您的应用程序的需求。

private class FileUploadTask extends AsyncTask<Object, Integer, Void> {

    private ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        dialog = new ProgressDialog(TheActivity.this);
        dialog.setMessage("Uploading...");
        dialog.setIndeterminate(false);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setProgress(0);
        dialog.show();
    }

    @Override
    protected Void doInBackground(Object... arg0) {
        try {
            File file = new File("file path");
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] bytes = new byte[(int) file.length()];
            fileInputStream.read(bytes);
            fileInputStream.close();

            URL url = new URL("some path");
            HttpURLConnection connection = 
                    (HttpURLConnection) url.openConnection();
            OutputStream outputStream = connection.getOutputStream();

            int bufferLength = 1024;
            for (int i = 0; i < bytes.length; i += bufferLength) {
                int progress = (int)((i / (float) bytes.length) * 100);
                publishProgress(progress);
                if (bytes.length - i >= bufferLength) {
                    outputStream.write(bytes, i, bufferLength);
                } else {
                    outputStream.write(bytes, i, bytes.length - i);
                }
            }
            publishProgress(100);

            outputStream.close();
            outputStream.flush();

            InputStream inputStream = connection.getInputStream();
            // read the response
            inputStream.close();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        dialog.setProgress(progress[0]);
    }

    @Override
    protected void onPostExecute(Void result) {
        try {
            dialog.dismiss();
        } catch(Exception e) {
        }

    }

}

【讨论】:

  • 这效率不高,因为它进展顺利,直到 100,然后在实际传输文件时对话框被关闭后卡在 100%。那么上面的代码中缺少什么?
  • 刷新 outputStream 时会开始实际上传。所以进度是假进度
  • 使用HttpURLConnection.setFixedLengthStreamingMode() 上传内容而不缓冲(参见@Songlin 回答)。
【解决方案2】:

我不认为 HttpURLConnection 只是简单地做到了这一点,正如@Basbous 指出的那样,实际数据被缓冲直到 outputStream.flush() 被调用。根据 android issue 3164,它现在已在 post-froyo 平台(android 2.2,sdk 版本 8)中修复,您需要使用 - java.net.HttpURLConnection.setFixedLengthStreamingMode 来解决缓冲区行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2011-07-03
    • 2012-08-06
    • 1970-01-01
    相关资源
    最近更新 更多