我希望将我的上传图片功能放在AsyncTask中。因此我改变了,它仍然有错误。 现在,我认为我的问题在onPostExecute。 httpURLConnection操作需要放入onPostExecute吗? 我应该改变什么? 谢谢你的帮助
class upload extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Loading....");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Saving product
* */
protected String doInBackground(String... args) {
{
String end = "\r\n";
String twoHyphens = "--";
String boundary = "******";
try
{
URL url = new URL(actionUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
// setting the memory
httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K
// allow input and output
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.setUseCaches(false);
// use POST way
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
httpURLConnection.setRequestProperty("Charset", "UTF-8");
httpURLConnection.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
DataOutputStream dos = new DataOutputStream(
httpURLConnection.getOutputStream());
dos.writeBytes(twoHyphens + boundary + end);
dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\"; filename=\""
+ srcPath.substring(srcPath.lastIndexOf("/") + 1)
+ "\""
+ end);
dos.writeBytes(end);
FileInputStream fis = new FileInputStream(srcPath);
byte[] buffer = new byte[8192]; // 8k
int count = 0;
while ((count = fis.read(buffer)) != -1)
{
dos.write(buffer, 0, count);
}
fis.close();
dos.writeBytes(end);
dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
dos.flush();
InputStream is = httpURLConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
String result = br.readLine();
dos.close();
is.close();
return result;
} catch (Exception e)
{
e.printStackTrace();
setTitle(e.getMessage());
}
}
return null;
}
protected void onPostExecute(String file_url) {
Toast.makeText(MainActivity.this, file_url, Toast.LENGTH_LONG).show();
// dismiss the dialog once product uupdated
pDialog.dismiss();
}
}
logcat的
04-22 09:01:53.381: E/AndroidRuntime(1154): FATAL EXCEPTION: AsyncTask #1
04-22 09:01:53.381: E/AndroidRuntime(1154): java.lang.RuntimeException: An error occured while executing doInBackground()
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.os.AsyncTask$3.done(AsyncTask.java:200)
04-22 09:01:53.381: E/AndroidRuntime(1154): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
04-22 09:01:53.381: E/AndroidRuntime(1154): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
04-22 09:01:53.381: E/AndroidRuntime(1154): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
04-22 09:01:53.381: E/AndroidRuntime(1154): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-22 09:01:53.381: E/AndroidRuntime(1154): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
04-22 09:01:53.381: E/AndroidRuntime(1154): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
04-22 09:01:53.381: E/AndroidRuntime(1154): at java.lang.Thread.run(Thread.java:1096)
04-22 09:01:53.381: E/AndroidRuntime(1154): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.view.View.invalidate(View.java:5139)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.widget.TextView.checkForRelayout(TextView.java:5364)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.widget.TextView.setText(TextView.java:2688)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.widget.TextView.setText(TextView.java:2556)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.widget.TextView.setText(TextView.java:2531)
04-22 09:01:53.381: E/AndroidRuntime(1154): at com.android.internal.policy.impl.PhoneWindow.setTitle(PhoneWindow.java:260)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.app.Activity.onTitleChanged(Activity.java:3581)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.app.Activity.setTitle(Activity.java:3547)
04-22 09:01:53.381: E/AndroidRuntime(1154): at com.example.mmap.MainActivity$upload.doInBackground(MainActivity.java:255)
04-22 09:01:53.381: E/AndroidRuntime(1154): at com.example.mmap.MainActivity$upload.doInBackground(MainActivity.java:1)
04-22 09:01:53.381: E/AndroidRuntime(1154): at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-22 09:01:53.381: E/AndroidRuntime(1154): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-22 09:01:53.381: E/AndroidRuntime(1154): ... 4 more
04-22 09:01:54.411: E/WindowManager(1154): Activity com.example.mmap.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@46047368 that was originally added here
04-22 09:01:54.411: E/WindowManager(1154): android.view.WindowLeaked: Activity com.example.mmap.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@46047368 that was originally added here
04-22 09:01:54.411: E/WindowManager(1154): at android.view.ViewRoot.<init>(ViewRoot.java:247)
04-22 09:01:54.411: E/WindowManager(1154): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
04-22 09:01:54.411: E/WindowManager(1154): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
04-22 09:01:54.411: E/WindowManager(1154): at android.view.Window$LocalWindowManager.addView(Window.java:424)
04-22 09:01:54.411: E/WindowManager(1154): at android.app.Dialog.show(Dialog.java:241)
04-22 09:01:54.411: E/WindowManager(1154): at com.example.mmap.MainActivity$upload.onPreExecute(MainActivity.java:187)
04-22 09:01:54.411: E/WindowManager(1154): at android.os.AsyncTask.execute(AsyncTask.java:391)
04-22 09:01:54.411: E/WindowManager(1154): at com.example.mmap.MainActivity$1.onClick(MainActivity.java:68)
04-22 09:01:54.411: E/WindowManager(1154): at android.view.View.performClick(View.java:2408)
04-22 09:01:54.411: E/WindowManager(1154): at android.view.View$PerformClick.run(View.java:8816)
04-22 09:01:54.411: E/WindowManager(1154): at android.os.Handler.handleCallback(Handler.java:587)
04-22 09:01:54.411: E/WindowManager(1154): at android.os.Handler.dispatchMessage(Handler.java:92)
04-22 09:01:54.411: E/WindowManager(1154): at android.os.Looper.loop(Looper.java:123)
04-22 09:01:54.411: E/WindowManager(1154): at android.app.ActivityThread.main(ActivityThread.java:4627)
04-22 09:01:54.411: E/WindowManager(1154): at java.lang.reflect.Method.invokeNative(Native Method)
04-22 09:01:54.411: E/WindowManager(1154): at java.lang.reflect.Method.invoke(Method.java:521)
04-22 09:01:54.411: E/WindowManager(1154): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
04-22 09:01:54.411: E/WindowManager(1154): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
04-22 09:01:54.411: E/WindowManager(1154): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:2)
删除返回结果,因为您无法从子视图返回。
删除
setTitle(e.getMessage());
并像这样重写postexecute
protected void onPostExecute(String file_url) {
// dismiss the dialog once product uupdated
pDialog.dismiss();
Toast.makeText(MainActivity.this, file_url, Toast.LENGTH_LONG).show();
}
答案 1 :(得分:1)
您似乎正在尝试在doInBackground()中更新ui。 doInBackground()在后台线程上运行。所以你需要在ui线程上更新ui。
你做如下
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
_tv.setText("myTitle");
}
});
http://developer.android.com/reference/android/os/AsyncTask.html
执行异步任务时,任务将经历4个步骤:
onPreExecute(),在执行任务之前在UI线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。
doInBackground(Params ...),在onPreExecute()完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。异步任务的参数将传递给此步骤。 此步骤必须返回计算结果,并将返回到最后一步。此步骤还可以使用publishProgress(Progress ...)发布一个或多个进度单元。这些值发布在UI线程的onProgressUpdate(Progress ...)步骤中。
onProgressUpdate(Progress ...),在调用publishProgress(Progress ...)后在UI线程上调用。执行的时间是不确定的。此方法用于在后台计算仍在执行时显示用户界面中的任何形式的进度。例如,它可用于为进度条设置动画或在文本字段中显示日志。
onPostExecute(Result),在后台计算完成后在UI线程上调用。背景计算的结果作为参数传递给此步骤。
在doInBackground()中返回结果并在onPostExecute()中更新ui
编辑:
从catch块中删除setTitle(e.getMessage())
protected String doInBackground(String... args)
{
.....
try
{
.......
result = "success" // example
}
catch (Exception e){
e.printStackTrace();
}
return result; // return result after catch
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
Toast.makeText(MainActivity.this, file_url, Toast.LENGTH_LONG).show();
}
答案 2 :(得分:0)
看起来像这个方法:
setTitle(e.getMessage());
从外部访问UI线程。 所有touchech UI都必须在doInBackground()方法之外完成。