在文件上传过程中显示进度条
我有一个应该在文件上传过程中显示进度的异步任务。除了它看起来完成文件上传的速度真的非常快之外,一切都在工作,然后它就在100%的等待中。在文件上传过程中显示进度条
我跟踪下来到
URL url = new URL(urlServer);
connection = (HttpURLConnection) url.openConnection();
// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Enable POST method
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"Filedata\";filename=\"" + pathToOurFile + "\"" + lineEnd);
outputStream.writeBytes(lineEnd);
long totalBytesWritten = 0;
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
outputStream.flush();
if (mCancel) { throw new CancelException(); }
totalBytesWritten += bufferSize;
if (mProgressDialog != null) {
mProgressDialog.setProgress(Integer.valueOf((int) (totalBytesWritten/1024L)));
}
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
我注意到的是,有没有真正的延迟,直到在那里的得到响应代码的最后一行。我认为发生的事情是数据缓冲,看起来好像已经上传了数据,但并不是真的 - 它只是缓冲了数据。然后,当我到达getResponseCode()调用时,它别无选择,只能完成上载以获取上传状态。有什么方法可以让它实际上传,让我可以得到合理的进展?
您可以使用进度对话框类,如下所示,
ProgressDialog progDailog = ProgressDialog.show(this,"Uploading", "Uploading File....",true,true);
new Thread (new Runnable()
{
public void run()
{
// your loading code goes here
}
}).start();
Handler progressHandler = new Handler()
{
public void handleMessage(Message msg1)
{
progDailog.dismiss();
}
}
这是邮政是如何设计的HTTP工作,所以不要指望它给你进步的详细信息。
您可以使用市场上的几种文件上传器组件之一。他们在内部使用flash或silverlight或iframe来显示进度。
http://dhtmlx.com/docs/products/dhtmlxVault/index.shtml
http://www.element-it.com/multiple-file-upload/flash-uploader.aspx
你会发现很多这样的人,如果你google了一下。
它们在内部使用原始IO代替http post来处理多个文件和进度通知。雅虎和谷歌也使用这些技术来制作邮件附件。
如果您真的很喜欢冒险,可以重新创建轮子 - 即编写您自己的组件。
编辑:
请注明,如果你想这样做在Windows桌面应用程序或Web应用程序。
您可以尝试使用的AsyncTask ...
创建onPreExecute方法的进度对话框,并驳回onPostExecute方法对话框..
请上传方法doInBackground()
例子:
public class ProgressTask extends AsyncTask<String, Void, Boolean> {
public ProgressTask(ListActivity activity) {
this.activity = activity;
dialog = new ProgressDialog(context);
}
/** progress dialog to show user that the backup is processing. */
private ProgressDialog dialog;
protected void onPreExecute() {
this.dialog.setMessage("Progress start");
this.dialog.show();
}
@Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
protected Boolean doInBackground(final String... args) {
//上传代码
return true;
}
}
}
HttpURLConnection.setFixedLengthStreamingMode(...)做到了!
你可以这样做:
try { // open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(
sourceFile);
URL url = new URL("http://10.0.2.2:9090/plugins/myplugin/upload");
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("uploadedfile", filename);
// conn.setFixedLengthStreamingMode(1024);
// conn.setChunkedStreamingMode(1);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\""
+ filename + "\"" + lineEnd);
dos.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = (int) sourceFile.length()/200;//suppose you want to write file in 200 chunks
buffer = new byte[bufferSize];
int sentBytes=0;
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
// Update progress dialog
sentBytes += bufferSize;
publishProgress((int)(sentBytes * 100/bytesAvailable));
bytesAvailable = fileInputStream.available();
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
// close streams
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}