上传图片时 ProgressDialog 不显示
Posted
技术标签:
【中文标题】上传图片时 ProgressDialog 不显示【英文标题】:ProgressDialog doesn't show when uploading Image 【发布时间】:2013-10-29 16:56:40 【问题描述】:我有一个用于将图像上传到服务器的类。 上传时我想显示一个progressDialog来显示上传的进度。 然而不知何故,进度条没有出现。 这是我的 ImageUploader 类:
package com.OBO.Bandenanalyse;
//Imagine Imports here
public class ImageUploader
private Context context;
private ProgressDialog dialog;
public ImageUploader(Context ctx)
this.context = ctx;
((Activity) context).runOnUiThread(new Runnable()
@Override
public void run()
dialog = new ProgressDialog(context);
dialog.setCancelable(false);
dialog.setMessage("Uploading Image... Please wait!");
dialog.show();
);
private static String serverResponseMessage = "";
private static int serverResponseCode = 0;
public int uploadFile(final String sourceFileUri, final String serverFile)
Debug.out("SourceFileUri: " + sourceFileUri);
Debug.out("ServerFile: " + serverFile);
Thread thread = new Thread()
@Override
public void run()
String upLoadServerUri = serverFile;
String fileName = sourceFileUri;
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File(sourceFileUri);
if (!sourceFile.isFile())
Log.e("uploadFile", "Source File Does not exist");
try // open a URL connection to the Servlet
Debug.out("in the try");
FileInputStream fileInputStream = new FileInputStream(
sourceFile);
URL url = new URL(upLoadServerUri);
conn = (HttpURLConnection) url.openConnection(); // Open a
// HTTP
// connection
// to
// the
// URL
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("uploaded_file", fileName);
dos = new DataOutputStream(conn.getOutputStream());
Debug.out("Set Properties and Datastream");
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
+ fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
Debug.out("Writes data");
bytesAvailable = fileInputStream.available(); // create a
// buffer of
// maximum
// size
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
Debug.out("Buffer done");
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
Debug.out("Read Bytes");
while (bytesRead > 0)
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
Debug.out("After sendData");
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
serverResponseMessage = conn.getResponseMessage();
Debug.out("Server Response: " + serverResponseCode);
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
Debug.out("HTTP Response is : " + serverResponseMessage
+ ": " + serverResponseCode);
// close the streams //
fileInputStream.close();
dos.flush();
dos.close();
dialog.dismiss();
catch (MalformedURLException ex)
dialog.dismiss();
ex.printStackTrace();
// Toast.makeText(UploadImageDemo.this,
// "MalformedURLException", Toast.LENGTH_SHORT).show();
Log.e("Upload file to server", "error: " + ex.getMessage(),
ex);
catch (Exception e)
dialog.dismiss();
e.printStackTrace();
// Toast.makeText(UploadImageDemo.this, "Exception : " +
// e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("Upload file to server Exception",
"Exception : " + e.getMessage(), e);
;
thread.start();
try
thread.join();
Debug.out("done uploading");
dialog.dismiss();
catch (InterruptedException e)
// TODO Auto-generated catch block
e.printStackTrace();
Debug.out("Message: " + serverResponseMessage.toString());
return serverResponseCode;
我在 AsyncTask 中调用该函数,因为我还需要做其他事情。我这样做是这样的:
private class MyAsyncTask extends AsyncTask<Mail, Integer, Double>
/**
* Private boolean to check if a tire is repairable or not.</br>
*/
boolean _repairable = Step4._isRepairable;
/**
* Private integer which counts how many times we've tried to send the Email.
*/
private int _counter = 0;
private ProgressDialog dialog;
@Override
protected void onPreExecute()
super.onPreExecute();
if(isPhotoTaken())
ImageUploader uploader = new ImageUploader(_context);
uploader.uploadFile(getPhotoPath(), "http://obo.nl/android-upload-image.php");
/**
* Method used to start @link #postData(Mail) on a background thread.
*
* @return null
*/
@Override
protected Double doInBackground(Mail... params)
postData(params[0]);
return null;
/**
* Method used to send the mail through a JSON Request in combination with the website.
* If there is no Internet connection the program will try to send the mail every 10 seconds.
*
* @param valueIWantToSend
*/
public void postData(Mail valueIWantToSend)
if(AppStatus.haveNetworkConnection(_context))
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://obo.nl/android-mailing.php");
try
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("from", valueIWantToSend.getFrom()));
nameValuePairs.add(new BasicNameValuePair("to", valueIWantToSend.getTo()));
nameValuePairs.add(new BasicNameValuePair("subject", valueIWantToSend.getSubject()));
nameValuePairs.add(new BasicNameValuePair("message", valueIWantToSend.getBody()));
nameValuePairs.add(new BasicNameValuePair("localized", getResources().getConfiguration().locale.getDisplayName()));
if(PathToPDF(_repairable).contains("Goed_Gekeurd_NL"))
nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_BANDENANALYSE_GOED_GEKEURD_PATH));
else if(PathToPDF(_repairable).contains("Afgekeurd_NL"))
nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_BANDENANALYSE_AFGEKEURD_PATH));
else if(PathToPDF(_repairable).contains("Goed_Gekeurd_FR"))
nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_ANALYSEPNEUS_GOED_GEKEURD_PATH));
else if(PathToPDF(_repairable).contains("Afgekeurd_FR"))
nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_ANALYSEPNEUS_AFGEKEURD_PATH));
else if(PathToPDF(_repairable).contains("Goed_Gekeurd_DE"))
nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_REIFENANALYSE_GOED_GEKEURD_PATH));
else if(PathToPDF(_repairable).contains("Afgekeurd_DE"))
nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_REIFENANALYSE_AFGEKEURD_PATH));
else if(PathToPDF(_repairable).contains("Goed_Gekeurd_EN"))
nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_TYREANALYSE_GOED_GEKEURD_PATH));
else if(PathToPDF(_repairable).contains("Afgekeurd_EN"))
nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_TYREANALYSE_AFGEKEURD_PATH));
if(isPhotoTaken())
// ImageUploader uploader = new ImageUploader(_context); // uploader.uploadFile(getPhotoPath(), "http://obo.nl/android-upload-image.php"); nameValuePairs.add(new BasicNameValuePair("照片", getPhotoPath())); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); ResponseHandler responseHandler = new BasicResponseHandler(); 字符串响应 = httpclient.execute(httppost, responseHandler);
//This is the response from a php application
String reverseString = response;
Log.i("info", reverseString);
catch (ClientProtocolException e)
catch (IOException e)
else
if(_counter == 0)
_counter++;
_activity.runOnUiThread(new Runnable()
public void run()
Toast.makeText(_context, getString(R.string.noInternetEmailNotSend), Toast.LENGTH_LONG).show();
);
try
Thread.sleep(10000);
catch (InterruptedException e)
e.printStackTrace();
postData(valueIWantToSend);
另外 _context 在活动的 onCreate 中是这样设置的:
_context = this;
在 PostData 方法中发生的事情是发送邮件,并将拍摄的照片作为附件(但这并不有趣,因为它工作得很好)。
那么为什么对话框没有出现呢?
【问题讨论】:
您可以在onPreExecute()
方法中创建对话框并在onPostExecute()
中关闭它,而不是在构造函数中创建对话框。
不,我不能,这太糟糕了。这是因为它仅用于上传图像。而 Asynctask 用于发送电子邮件。 (需要在附加之前上传图片)。
【参考方案1】:
首先,当您在 AsyncTask 的 onPreExecute() 中为 ImageUpLoader 创建对象时,您无需在构造函数中专门调用 runOnUIThread() 方法,因为 onPreExecute 在 UI 线程上运行并进行对话,试试这个... 删除 thread.join() 语句,
Thread thread = new Thread()
public void run()
// your upload code stuff here
activity.runOnUiThread(new Runnable()
public void run()
if(dialog.isShowing())
dialog.dismiss();
当 UI 组件在 UI Thread 中创建时,它们很可能需要在 UI Thread 中处理。 (试图关闭新线程中的对话框)
【讨论】:
Hmmm 这行不通,因为tread.join用于检查线程是否完成了图像的上传。【参考方案2】:您没有在 ImageUploader 方法中启动线程。将您的方法更改为:
public ImageUploader(Context ctx)
this.context = ctx;
((Activity) context).runOnUiThread(new Runnable()
@Override
public void run()
dialog = new ProgressDialog(context);
dialog.setCancelable(false);
dialog..setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage("Uploading Image... Please wait!");
dialog.show();
).start();
【讨论】:
嗯,如果我添加 .start();它不会再编译了:Cannot invoke Start() on primitive type void。 .start() 是必要的,因为您的线程永远不会启动。可能是因为您没有设置 ProgressDialog 样式。我已经编辑了我的答案再次测试它。 即使添加了样式,它仍然不起作用。然而我确信我应该开始这个话题 你为什么使用 rubOnUiThread?正常线程有什么问题?因为我使用普通线程来等待用户对话框并且工作得很好。 那是因为它是一个 UI 元素,所以从技术上讲它应该在 UI 线程上运行,但让我尝试将它放在普通线程上。以上是关于上传图片时 ProgressDialog 不显示的主要内容,如果未能解决你的问题,请参考以下文章