简体   繁体   English

Android-AsyncTask中的doInBackground()错误

[英]Android - doInBackground() error in AsyncTask

What my app here basically does is it captures a photo or import from gallery, and when the Upload button is pressed, the image will be uploaded to a localhost server. 我在这里的应用程序基本上要做的是捕获照片或从图库中导入,然后按下“上传”按钮,图像将被上传到本地服务器。

Before I implemented AsyncTask into the process, it doesn't have any problem uploading whatsoever. 在将AsyncTask实施到流程中之前,上传任何内容都没有问题。 Now that I've put AsyncTask, everything went wrong. 既然我已经放置了AsyncTask,一切都会出错。

I don't know which part that I do wrong in this phase. 我不知道在此阶段我做错了哪些部分。 This is what logcat shows when I try to upload an image file: 这是我尝试上载图像文件时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)

This is my code for the Upload activity: 这是我上载活动的代码:

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();
    }
}

Can someone please check if I put the AsyncTask task correctly in this activity? 有人可以检查我是否在此活动中正确放置了AsyncTask任务吗? I think I've made a mistake somewhere. 我想我在某个地方犯了一个错误。

Please remove Toast from catch block 请从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());
                }

instead use this to see your error in logcat, 而是使用它来查看logcat中的错误,

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

While executing AsyncTask, You can't show toast or progress dialog inside the same thread. 在执行AsyncTask时,您无法在同一线程内显示Toast或Progress对话框。 Use Handler to show toast or progress dialog instead. 使用处理程序来显示吐司或进度对话框。

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;
        }
    }

And the handler : 和处理程序:

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);
   }
    };

Don't show toast or alert in doInBackground.Do that in onPostExecute 不要在doInBackground中显示敬酒或警报,请在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);

Remove toast from the method doInBackground(String... params) because the thread not allow to show/ update current view. 从方法doInBackground(String... params)移除toast,因为该线程不允许显示/更新当前视图。 When you want to show then use runOnUIthread. 当您想要显示时,请使用runOnUIthread.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM