运行时异常无法在未调用looper.prepare错误的线程内创建处理程序

时间:2013-08-29 13:50:22

标签: java android upload photo

我正在尝试使用其他一些EditText上传照片。 我从一个在线示例中获取了示例代码并对其进行了编辑 我收到了这个错误:

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

我的Android代码:

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

}
}

请告诉我这里的问题是什么,如何提前解决,我该如何解决? 我知道常见的答案是我需要从UI线程调用Toast.makeText(...): 我很抱歉,因为我对这个很新,有没有人介意更详细地解释这个

1 个答案:

答案 0 :(得分:2)

可能因为这行

而出现错误
 Toast.makeText(getApplicationContext(),
                    e.getMessage(),
                    Toast.LENGTH_LONG).show();

doInBackground内。Toast必须在UIThread上显示。而是使用doInBackground线程来显示它。通常,关于UI的所有操作都必须在UI线程上执行。如果要修复,可以使用处理程序在显示Toast的UI Thread队列中发布runnable