我正在我的项目中实现AsyncTask。 onPrexecute显示对话框,但沿着该行,应用程序崩溃并出现错误。
java.lang.RuntimeException: An error occured while executing doInBackground()
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
这是我的AsycTask任务代码
private class CheckTypesTask extends AsyncTask<Void, Void, Void>{
ProgressDialog asyncDialog = new ProgressDialog(MainActivity.this);
String typeStatus;
@Override
protected void onPreExecute() {
//set message of the dialog
asyncDialog.setMessage("Please wait");
//show dialog
asyncDialog.show();
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... arg0) {
onPhotoTaken();
return null;
}
@Override
protected void onPostExecute(Void result) {
//hide the dialog
asyncDialog.dismiss();
asyncDialog = null;
super.onPostExecute(result);
}
}
经过研究,我将代码修改为
@Override
protected Void doInBackground(Void... arg0) {
runOnUiThread(new Runnable() {
@Override
public void run() {
onPhotoTaken();
}
});
return null;
}
EDITTED: 这是onPhoto拍摄方法
public void onPhotoTaken() {
_taken = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(_path, options);
try {
//ProgressDialog dialog = ProgressDialog.show(this, "Loading", "Please wait...", true);
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
Log.v(TAG, "Orient: " + exifOrientation);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
Log.v(TAG, "Rotation: " + rotate);
if (rotate != 0) {
// Getting width & height of the given image.
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
}
// Convert to ARGB_8888, required by tess
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
//dialog.dismiss();
} catch (IOException e) {
Log.e(TAG, "Couldn't correct orientation: " + e.toString());
}
_image.setImageBitmap(bitmap);
此时效果很好,但我的代码显示为空白屏幕。 在期待中感谢
答案 0 :(得分:1)
您必须在_image.setImageBitmap(bitmap);
方法上使用onPostExecute
。
onPostExecute在UI线程上运行。
根据经验,从不修改View
帖子之外的main(UI)
。
答案 1 :(得分:0)
试试这个(并让你的onPhotoTaken返回一个Bitmap而不是设置它):
private class CheckTypesTask extends AsyncTask<Void, Void, Bitmap>{
ProgressDialog asyncDialog = new ProgressDialog(MainActivity.this);
String typeStatus;
@Override
protected void onPreExecute() {
//set message of the dialog
asyncDialog.setMessage("Please wait");
//show dialog
asyncDialog.show();
super.onPreExecute();
}
@Override
protected Bitmap doInBackground(Void... arg0) {
return onPhotoTaken();
}
@Override
protected void onPostExecute(Bitmap result) {
//hide the dialog
asyncDialog.dismiss();
asyncDialog = null;
if (result != null) {
_image.setImageBitmap(result);
}
super.onPostExecute(result);
}
}
因此,您的doInBackground函数返回位图而不是将其应用于图像。 onPostExecute在UI线程中运行,您可以毫无问题地操作像Imageview这样的UI元素。