我收到了這個錯誤,我不明白爲什麼。我對Java相當陌生。我想要做的是啓動一個新的線程,它將處理所有的保存圖像過程。Android:無法在未調用Looper.prepare()的線程中創建處理程序運行新線程
錯誤:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.app.Dialog.<init>(Dialog.java:108)
at android.app.AlertDialog.<init>(AlertDialog.java:125)
at android.app.AlertDialog$Builder.create(AlertDialog.java:967)
at android.app.AlertDialog$Builder.show(AlertDialog.java:986)
at com.example.matts.myapplication.MainActivity$1.handleMessage(MainActivity.java:37)
at com.example.matts.myapplication.Saving.run(Saving.java:54)
at java.lang.Thread.run(Thread.java:818)
這裏是我的代碼。
Main:
package com.example..myapplication;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.text.SimpleDateFormat;
public class MainActivity extends Activity {
static final int REQUEST_IMAGE_CAPTURE = 1;
ImageView imageView;
private static final String TAG = "MyActivity";
Bitmap image;
Handler goodHandler = new Handler() {
@Override
public void handleMessage(Message message) {
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setMessage("File Saved").show();
}
};
Handler badHandler = new Handler() {
@Override
public void handleMessage(Message message) {
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setMessage("File Save failed").show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
openCamera();
setContentView(R.layout.activity_main);
findViewById(R.id.captureImage).bringToFront();
findViewById(R.id.saveImage).bringToFront();
imageView = (ImageView) findViewById(R.id.imageView2);
}
protected void onSaveInstanceState(Bundle outState){
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "TMP.jpg");
file.delete();
}
public void openCamera() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "TMP.jpg");
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//Check that request code matches ours:
if (requestCode == REQUEST_IMAGE_CAPTURE) {
//Get our saved file into a bitmap object:
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "TMP.jpg");
Bitmap image = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);
imageView.setImageBitmap(image);
}
}
// Reduce the amount of dynamic heap used by expanding the JPEG into a memory array that's already scaled to match the size of the destination view
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) { // BEST QUALITY MATCH
//First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize, Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > reqHeight) {
inSampleSize = Math.round((float) height/(float) reqHeight);
}
int expectedWidth = width/inSampleSize;
if (expectedWidth > reqWidth) {
//if(Math.round((float)width/(float)reqWidth) > inSampleSize) // If bigger SampSize..
inSampleSize = Math.round((float) width/(float) reqWidth);
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
public void capture_btn(View v) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "TMP.jpg");
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
public void storeImage(Bitmap image) {
imageView.buildDrawingCache();
Bitmap bm_img = imageView.getDrawingCache();
Saving saving = new Saving(bm_img, goodHandler, badHandler);
Thread thread = new Thread(saving);
thread.start();
}
public void save_btn(View v) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
storeImage(image);
break;
case DialogInterface.BUTTON_NEGATIVE:
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure?").setPositiveButton("Yes", dialogClickListener)
.setNegativeButton("No", dialogClickListener).show();
} //notification messages
}
保存:
package com.example..myapplication;
import android.graphics.Bitmap;
import android.os.Environment;
import android.os.Message;
import android.util.Log;
import android.os.Handler;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Saving implements Runnable {
private Bitmap image;
private android.os.Handler goodHandler;
private android.os.Handler badHandler;
private static final String TAG = "Saving";
public Saving(Bitmap in, Handler hinGood,Handler hinBad) {
image = in;
goodHandler = hinGood;
badHandler = hinBad;
}
@Override
public void run() {
File file = getOutputMediaFile();
if (file == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(file);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
badHandler.handleMessage(new Message());
return;
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
badHandler.handleMessage(new Message());
return;
}
goodHandler.handleMessage(new Message());
}
public File getOutputMediaFile(){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Pictures/Wiki_camera"
+ "/Photos");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
File mediaFile;
String mImageName="camera_wiki"+ timeStamp +".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
}
我已經添加了整個主類和儲蓄類的。
請發送'storeImage()'代碼。 – pathfinderelite
完成,添加到問題。 – smither123
「goodHandler」和「badHandler」在哪裏定義? – pathfinderelite