Being able to display a progress bar during a time consuming upload to a web server is important when dealing with users and appeasing their impatience. Here is one approach of achieving this.
In this example we are going to use 2 classes – the first one is going to implement Android’s really handy threading function: Async Task and the other is going to extend MutlipartEntity – the basic object used for a multipart POST. Let’s take a look at extending a MultipartEntity object:
CustomMultiPartEntity.java
[java]view plaincopy
importjava.io.FilterOutputStream;
importjava.io.IOException;
importjava.io.OutputStream;
importjava.nio.charset.Charset;
importorg.apache.http.entity.mime.HttpMultipartMode;
importorg.apache.http.entity.mime.MultipartEntity;
publicclassCustomMultiPartEntityextendsMultipartEntity
{
privatefinalProgressListenerlistener;
publicCustomMultiPartEntity(finalProgressListenerlistener)
{
super();
this.listener=listener;
}
publicCustomMultiPartEntity(finalHttpMultipartModemode,finalProgressListenerlistener)
{
super(mode);
this.listener=listener;
}
publicCustomMultiPartEntity(HttpMultipartModemode,finalStringboundary,finalCharsetcharset,finalProgressListenerlistener)
{
super(mode,boundary,charset);
this.listener=listener;
}
@Override
publicvoidwriteTo(finalOutputStreamoutstream)throwsIOException
{
super.writeTo(newCountingOutputStream(outstream,this.listener));
}
publicstaticinterfaceProgressListener
{
voidtransferred(longnum);
}
publicstaticclassCountingOutputStreamextendsFilterOutputStream
{
privatefinalProgressListenerlistener;
privatelongtransferred;
publicCountingOutputStream(finalOutputStreamout,finalProgressListenerlistener)
{
super(out);
this.listener=listener;
this.transferred=0;
}
publicvoidwrite(byte[]b,intoff,intlen)throwsIOException
{
out.write(b,off,len);
this.transferred+=len;
this.listener.transferred(this.transferred);
}
publicvoidwrite(intb)throwsIOException
{
out.write(b);
this.transferred++;
this.listener.transferred(this.transferred);
}
}
}
By simply counting the amount of bytes that are written, we can implement an interface (here we called it trasnfered())which can be called in our main class to update our progress bar dialog box:
Main.java
[java]view plaincopy
classHttpMultipartPostextendsAsyncTask<HttpResponse,Integer,TypeUploadImage>
{
ProgressDialogpd;
longtotalSize;
@Override
protectedvoidonPreExecute()
{
pd=newProgressDialog(this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("UploadingPicture...");
pd.setCancelable(false);
pd.show();
}
@Override
protectedTypeUploadImagedoInBackground(HttpResponse...arg0)
{
HttpClienthttpClient=newDefaultHttpClient();
HttpContexthttpContext=newBasicHttpContext();
HttpPosthttpPost=newHttpPost("/UploadImage.php");
try
{
CustomMultipartEntitymultipartContent=newCustomMultipartEntity(newProgressListener()
{
@Override
publicvoidtransferred(longnum)
{
publishProgress((int)((num/(float)totalSize)*100));
}
});
//WeuseFileBodytotransferanimage
multipartContent.addPart("uploaded_file",newFileBody(newFile(m_userSelectedImagePath)));
totalSize=multipartContent.getContentLength();
//Sendit
httpPost.setEntity(multipartContent);
HttpResponseresponse=httpClient.execute(httpPost,httpContext);
StringserverResponse=EntityUtils.toString(response.getEntity());
ResponseFactoryrp=newResponseFactory(serverResponse);
return(TypeImage)rp.getData();
}
catch(Exceptione)
{
System.out.println(e);
}
returnnull;
}
@Override
protectedvoidonProgressUpdate(Integer...progress)
{
pd.setProgress((int)(progress[0]));
}
@Override
protectedvoidonPostExecute(TypeUploadImageui)
{
pd.dismiss();
}
原文