0

我希望把我的上传图片功能放在 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)
4

3 回答 3

2

移除返回结果,因为不能从子视图返回。
消除

setTitle(e.getMessage());

从 doinbackground 并像这样重写 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();
 }
于 2013-04-22T09:35:06.630 回答
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 个步骤:

  1. onPreExecute(),在任务执行之前在 UI 线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。

  2. doInBackground(Params...),在 onPreExecute() 完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。异步任务的参数传递到这一步。计算的结果必须由这一步返回,并将传回最后一步。此步骤还可以使用 publishProgress(Progress...) 来发布一个或多个进度单位。这些值在 UI 线程上的 onProgressUpdate(Progress...) 步骤中发布。

  3. onProgressUpdate(Progress...),在调用 publishProgress(Progress...) 后在 UI 线程上调用。执行的时间是不确定的。此方法用于在后台计算仍在执行时在用户界面中显示任何形式的进度。例如,它可用于动画进度条或在文本字段中显示日志。

  4. 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();
   }
于 2013-04-22T09:47:50.623 回答
0

它看起来像这种方法:

setTitle(e.getMessage()); 

正在从外部访问 UI 线程。所有 touchech UI 都必须在 doInBackground() 方法之外完成。

于 2013-04-22T09:37:53.990 回答