【问题标题】:Android - doInBackground() error in AsyncTaskAndroid - AsyncTask 中的 doInBackground() 错误
【发布时间】:2013-10-28 09:40:45
【问题描述】:

我的应用在这里的主要作用是捕捉照片或从图库导入,当按下上传按钮时,图像将上传到本地服务器。

在我将 AsyncTask 实施到流程中之前,它没有任何上传问题。现在我已经放了 AsyncTask,一切都出错了。

我不知道我在这个阶段做错了什么。这是我尝试上传图像文件时 logcat 显示的内容:

10-28 17:23:25.989: E/AndroidRuntime(3356): FATAL EXCEPTION: AsyncTask #5
10-28 17:23:25.989: E/AndroidRuntime(3356): java.lang.RuntimeException: An error occured while executing doInBackground()
10-28 17:23:25.989: E/AndroidRuntime(3356):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at java.lang.Thread.run(Thread.java:856)
10-28 17:23:25.989: E/AndroidRuntime(3356): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
10-28 17:23:25.989: E/AndroidRuntime(3356):     at android.os.Handler.<init>(Handler.java:197)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at android.os.Handler.<init>(Handler.java:111)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at android.widget.Toast$TN.<init>(Toast.java:324)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at android.widget.Toast.<init>(Toast.java:91)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at android.widget.Toast.makeText(Toast.java:238)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at com.aiman.webshopper.UploadImageActivity$1execMultiPostAsync.doInBackground(UploadImageActivity.java:268)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at com.aiman.webshopper.UploadImageActivity$1execMultiPostAsync.doInBackground(UploadImageActivity.java:1)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-28 17:23:25.989: E/AndroidRuntime(3356):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)

这是我上传活动的代码:

public class UploadImageActivity extends Activity implements
        OnItemSelectedListener {
    InputStream inputStream;
    private ImageView imageView;

    String the_string_response;

    private static final int SELECT_PICTURE = 0;
    private static final int CAMERA_REQUEST = 1888;

    private static final String SERVER_UPLOAD_URI = "...myserver.php";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upload_image);

        imageView = (ImageView) findViewById(R.id.imgUpload);
    }


    public void capturePhoto(View view) {
        Intent cameraIntent = new Intent(
                android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        File f = new File(android.os.Environment.getExternalStorageDirectory(),
                "temp.jpg");
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
        startActivityForResult(cameraIntent, CAMERA_REQUEST);
    }

    public void pickPhoto(View view) {
        // TODO: launch the photo picker
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Picture"),
                SELECT_PICTURE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
            File f = new File(Environment.getExternalStorageDirectory()
                    .toString());
            for (File temp : f.listFiles()) {
                if (temp.getName().equals("temp.jpg")) {
                    f = temp;
                    break;
                }
            }
            try {
                BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();

                Bitmap bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),
                        bitmapOptions);

                imageView.setImageBitmap(bitmap);

                String path = android.os.Environment
                        .getExternalStorageDirectory()
                        + File.separator
                        + "Phoenix" + File.separator + "default";
                f.delete();
                OutputStream outFile = null;
                File file = new File(path, String.valueOf(System
                        .currentTimeMillis()) + ".jpg");

                try {
                    outFile = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outFile);
                    outFile.flush();
                    outFile.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (requestCode == SELECT_PICTURE && resultCode == RESULT_OK) {
            Bitmap bitmap = getPath(data.getData());
            imageView.setImageBitmap(bitmap);
        }
    }

    private Bitmap getPath(Uri uri) {

        String[] projection = { MediaStore.Images.Media.DATA };

        Cursor cursor = getContentResolver().query(uri, projection, null, null,
                null);
        int column_index = cursor.getColumnIndexOrThrow(projection[0]);
        cursor.moveToFirst();
        String filePath = cursor.getString(column_index);
        cursor.close();
        // Convert file path into bitmap image using below line.
        Bitmap bitmap = BitmapFactory.decodeFile(filePath);
        return bitmap;
    }

    public void uploadPhoto(View view) {
        try {
            executeMultipartPost();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void executeMultipartPost() throws Exception {

        class execMultiPostAsync extends AsyncTask<String, Void, String>{
            @Override
            protected String doInBackground(String... params){
                // Choose image here
                BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
                Bitmap bitmap = drawable.getBitmap();
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream); // compress to
                                                                            // which
                                                                            // format
                                                                            // you want.
                byte[] byte_arr = stream.toByteArray();
                String image_str = Base64.encodeBytes(byte_arr);
                ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

                nameValuePairs.add(new BasicNameValuePair("image", image_str));

                try {
                    HttpClient httpclient = new DefaultHttpClient();
                    /*
                     * HttpPost(parameter): Server URI
                     */
                    HttpPost httppost = new HttpPost(SERVER_UPLOAD_URI);
                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                    HttpResponse response = httpclient.execute(httppost);
                    the_string_response = convertResponseToString(response);
                } catch (Exception e) {
                    Toast.makeText(UploadImageActivity.this, "ERROR " + e.getMessage(),
                            Toast.LENGTH_LONG).show();
                    System.out.println("Error in http connection " + e.toString());
                }

                return the_string_response;
            }

            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);

                Toast.makeText(UploadImageActivity.this,
                        "Response " + result, Toast.LENGTH_LONG)
                        .show();

            }

            public String convertResponseToString(HttpResponse response)
                    throws IllegalStateException, IOException {

                String res = "";
                StringBuffer buffer = new StringBuffer();
                inputStream = response.getEntity().getContent();
                int contentLength = (int) response.getEntity().getContentLength(); // getting
                                                                                    // content
                                                                                    // lengt
                Toast.makeText(UploadImageActivity.this,
                        "contentLength : " + contentLength, Toast.LENGTH_LONG).show();
                if (contentLength < 0) {
                } else {
                    byte[] data = new byte[512];
                    int len = 0;
                    try {
                        while (-1 != (len = inputStream.read(data))) {
                            buffer.append(new String(data, 0, len)); // converting to
                                                                        // string and
                                                                        // appending to
                                                                        // stringbuffer
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        inputStream.close(); // closing the stream
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    res = buffer.toString(); // converting stringbuffer to string

                    Toast.makeText(UploadImageActivity.this, "Result : " + res,
                            Toast.LENGTH_LONG).show();
                    // System.out.println("Response => " +
                    // EntityUtils.toString(response.getEntity()));
                }
                return res;
            }
        }

        execMultiPostAsync exec = new execMultiPostAsync();
        exec.execute();
    }
}

有人可以检查我是否将 AsyncTask 任务正确放入此活动中吗?我想我在某个地方犯了一个错误。

【问题讨论】:

  • 不要在 doInBackground 中显示 toast 或警报。在 onPostExecute 中执行此操作
  • 从 InBackground() 中删除 toast 和 log 语句(如果不是)

标签: java android


【解决方案1】:

请从catch 块中删除Toast

try {
                    HttpClient httpclient = new DefaultHttpClient();
                    /*
                     * HttpPost(parameter): Server URI
                     */
                    HttpPost httppost = new HttpPost(SERVER_UPLOAD_URI);
                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                    HttpResponse response = httpclient.execute(httppost);
                    the_string_response = convertResponseToString(response);
                } catch (Exception e) {
                    Toast.makeText(UploadImageActivity.this, "ERROR " + e.getMessage(),
                            Toast.LENGTH_LONG).show();
                    System.out.println("Error in http connection " + e.toString());
                }

改为使用它在 logcat 中查看您的错误,

catch(Exception exception)
            {
                exception.printStackTrace();
                return false;
            }

【讨论】:

    【解决方案2】:

    在执行 AsyncTask 时,您无法在同一线程内显示 toast 或进度对话框。改为使用 Handler 来显示 toast 或进度对话框。

    public class SendPasscode extends AsyncTask<Void, Void, Void> {
    
            @Override
            protected void onPreExecute() {
                // TODO Auto-generated method stub
                super.onPreExecute();
               // Showing progress dialog in handler.
                mHandler.sendEmptyMessage(SHOW_PROGRESS);
            }
    
            @Override
            protected void onPostExecute(Void result) {
                // TODO Auto-generated method stub
                super.onPostExecute(result);
                mHandler.sendEmptyMessage(STOP_PROGRESS);
            }
    
            @Override
            protected Void doInBackground(Void... params) {
                // TODO Auto-generated method stub
    
    
    
                try {
                    JSONObject json = JSONfunctions
                            .getJSONfromURL(
                                    Constant.API_BASE_PATH
                                            + "create_passcode?mid="
                                            + Utils.getMerchantId(ChooseApplicationActivity.this)
                                            + "&pass_code=" + finalString,
                                    ChooseApplicationActivity.this);
    
                    if (json != null) {
    
                        String passcodeStatus = json.getJSONObject("response")
                                .getString("status");
                        if (passcodeStatus.equals("1")) {
                            mJsonResponse = json.getJSONObject("response")
                                    .getString("message");
                            Utils.savePasscode(finalString,
                                    ChooseApplicationActivity.this);
                            mHandler.sendEmptyMessage(RESULT_SUCCESS);
                        } else {
                            mJsonResponse = json.getJSONObject("response")
                                    .getString("error");
                            mHandler.sendEmptyMessage(RESULT_SUCCESS);
                        }
                    } else {
                        mHandler.sendEmptyMessage(PROBLEM_IN_CONNECTING_SERVER);
                    }
                } catch (Exception e) {
                    Log.d("Exceptions",
                            " The Xception messages are " + e.getMessage());
                }
                return null;
            }
        }
    

    还有处理程序:

    private Handler mHandler = new Handler() {
    
            private ProgressDialog progressDialog;
    
            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                switch (msg.what) {
                case SHOW_PROGRESS:
                    if (progressDialog == null) {
                        progressDialog = Utils
                                .createProgressDialog(ChooseApplicationActivity.this);
                        progressDialog.show();
                    } else {
                        progressDialog.show();
                    }
                    mHandler.removeMessages(SHOW_PROGRESS);
                    break;
    
                case STOP_PROGRESS:
                    progressDialog.dismiss();
                    mHandler.removeMessages(STOP_PROGRESS);
                    break;
    
                case NETWORK_FAILURE:
    
    
            Utils.displayToast(ChooseApplicationActivity.this,
                        Constant.NO_NETWORK_AVAIL);
                mHandler.removeMessages(NETWORK_FAILURE);
                break;
              }
        super.handleMessage(msg);
       }
        };
    

    【讨论】:

      【解决方案3】:

      不要在 doInBackground 中显示 toast 或 alert。在 onPostExecute 中这样做

      AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
      
          @Override
          protected void onPreExecute() {
               //Show UI
      
          }
      
          @Override
          protected Void doInBackground(Void... arg0) {
               // do your background process 
              return null;
          }
      
          @Override
          protected void onPostExecute(Void result) {
                            //Show UI (Toast msg here)
      
          }
      
          };
      
          task.execute((Void[])null);
      

      【讨论】:

        【解决方案4】:

        从方法 doInBackground(String... params) 中删除 toast,因为线程不允许显示/更新当前视图。当你想显示然后使用runOnUIthread.

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-05
          • 1970-01-01
          • 1970-01-01
          • 2014-04-17
          相关资源
          最近更新 更多