runtime exception can't create handler inside thread that has not called looper.prepare error

大城市里の小女人 提交于 2019-12-31 07:33:07

问题


I am trying to upload a photo with a few other EditText. I got the sample code from an online example and edited it alittle but I'm receiving this error:

08-29 21:36:46.000: E/AndroidRuntime(4566): FATAL EXCEPTION: AsyncTask #1
08-29 21:36:46.000: E/AndroidRuntime(4566): java.lang.RuntimeException: An error occured while executing doInBackground()
08-29 21:36:46.000: E/AndroidRuntime(4566):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at java.lang.Thread.run(Thread.java:856)
08-29 21:36:46.000: E/AndroidRuntime(4566): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
08-29 21:36:46.000: E/AndroidRuntime(4566):     at android.os.Handler.<init>(Handler.java:121)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at android.widget.Toast$TN.<init>(Toast.java:361)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at android.widget.Toast.<init>(Toast.java:97)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at android.widget.Toast.makeText(Toast.java:254)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at com.example.imageupload.ImageUpload$ImageUploadTask.doInBackground(ImageUpload.java:177)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at com.example.imageupload.ImageUpload$ImageUploadTask.doInBackground(ImageUpload.java:1)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
08-29 21:36:46.000: E/AndroidRuntime(4566):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-29 21:36:46.000: E/AndroidRuntime(4566):     ... 5 more

My Android Codes:

package com.example.imageupload;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

public class ImageUpload extends Activity {
private static final int PICK_IMAGE = 1;
private ImageView imgView;
private Button upload;
private EditText TraineeID, ExamID, Invoiceno;
private Bitmap bitmap;
private ProgressDialog dialog;
private String url = "www.orgaar.com/androidlogin/imageupload.php";

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.uploadimage);

    imgView = (ImageView) findViewById(R.id.ImageView);
    upload = (Button) findViewById(R.id.Upload);
    Invoiceno = (EditText) findViewById(R.id.Invoiceno);
    TraineeID = (EditText) findViewById(R.id.TraineeID);
    ExamID = (EditText) findViewById(R.id.ExamID); 
    upload.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            if (bitmap == null) {
                Toast.makeText(getApplicationContext(),
                        "Please select image", Toast.LENGTH_SHORT).show();
            } else {
                dialog = ProgressDialog.show(ImageUpload.this, "Uploading",
                        "Please wait...", true);
                new ImageUploadTask().execute();
            }
        }
    });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.imageupload_menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
    case R.id.ic_menu_gallery:
        try {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(
                    Intent.createChooser(intent, "Select Picture"),
                    PICK_IMAGE);
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(),
                    e.getMessage(),
                    Toast.LENGTH_LONG).show();
            Log.e(e.getClass().getName(), e.getMessage(), e);
        }
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case PICK_IMAGE:
        if (resultCode == Activity.RESULT_OK) {
            Uri selectedImageUri = data.getData();
            String filePath = null;

            try {
                // OI FILE Manager
                String filemanagerstring = selectedImageUri.getPath();

                // MEDIA GALLERY
                String selectedImagePath = getPath(selectedImageUri);

                if (selectedImagePath != null) {
                    filePath = selectedImagePath;
                } else if (filemanagerstring != null) {
                    filePath = filemanagerstring;
                } else {
                    Toast.makeText(getApplicationContext(), "Unknown path",
                            Toast.LENGTH_LONG).show();
                    Log.e("Bitmap", "Unknown path");
                }

                if (filePath != null) {
                    decodeFile(filePath);
                } else {
                    bitmap = null;
                }
            } catch (Exception e) {
                Toast.makeText(getApplicationContext(), "Internal error",
                        Toast.LENGTH_LONG).show();
                Log.e(e.getClass().getName(), e.getMessage(), e);
            }
        }
        break;
    default:
    }
}


class ImageUploadTask extends AsyncTask<Void, Void, String> {
    @Override
    protected String doInBackground(Void... unsued) {
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpContext localContext = new BasicHttpContext();
            HttpPost httpPost = new HttpPost(url);

            MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bitmap.compress(CompressFormat.JPEG, 100, bos);
            byte[] data = bos.toByteArray();
            entity.addPart("returnformat", new StringBody("json"));
            entity.addPart("uploaded", new ByteArrayBody(data,"myImage.jpg"));
            entity.addPart("Invoiceno", new StringBody(Invoiceno.getText().toString()));
            entity.addPart("TraineeID", new StringBody(TraineeID.getText().toString()));
            entity.addPart("ExamID", new StringBody(ExamID.getText().toString()));
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost,
                    localContext);
            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));

            String sResponse = reader.readLine();
            return sResponse;
            } catch (Exception e) {
            if (dialog.isShowing())
                dialog.dismiss();
            Toast.makeText(getApplicationContext(),
                    e.getMessage(),
                    Toast.LENGTH_LONG).show();
            Log.e(e.getClass().getName(), e.getMessage(), e);
            return null;
        }

        // (null);
    }

    @Override
    protected void onProgressUpdate(Void... unsued) {

    }

    @Override
    protected void onPostExecute(String sResponse) {
        try {
            if (dialog.isShowing())
                dialog.dismiss();

            if (sResponse != null) {
                JSONObject JResponse = new JSONObject(sResponse);
                int success = JResponse.getInt("SUCCESS");
                String message = JResponse.getString("MESSAGE");
                if (success == 0) {
                    Toast.makeText(getApplicationContext(), message,
                            Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(),
                            "Photo uploaded successfully",
                            Toast.LENGTH_SHORT).show();
                    Invoiceno.setText("");
                }
            }
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(),
                    e.getMessage(),
                    Toast.LENGTH_LONG).show();
            Log.e(e.getClass().getName(), e.getMessage(), e);
        }
    }
}

public String getPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    if (cursor != null) {
        // HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
        // THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } else
        return null;
}

public void decodeFile(String filePath) {
    // Decode image size

    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, o);

    // The new size we want to scale to
    final int REQUIRED_SIZE = 1024;

    // Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;
    while (true) {
        if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
            break;
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    // Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    bitmap = BitmapFactory.decodeFile(filePath, o2);

    imgView.setImageBitmap(bitmap);

}
}

Please tell me whats is the problem here and how can I solve it thanks in advance I know that the common answer is that I need to call Toast.makeText(...) from the UI thread: I am sorry as i am very new to this does anyone mind explaining this in more detail


回答1:


Probably the error arise because of this line

 Toast.makeText(getApplicationContext(),
                    e.getMessage(),
                    Toast.LENGTH_LONG).show();

inside doInBackground.Toast has to been shown on the UIThread. Instead you are using the doInBackground thread to show it. In general, all the operations regarding the UI have to be executed on the UI Thread. If you want to fix, you could use an handler to post a runnable on the UI Thread queue that shows a Toast



来源:https://stackoverflow.com/questions/18512841/runtime-exception-cant-create-handler-inside-thread-that-has-not-called-looper

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!