我的应用程序中有一个奇怪的错误,当我从相机应用程序返回后,在拍照后,活动会在无限循环中重新启动它。
UI流程如下:
奇怪的是,它只发生在一些相机上。在运行Jellybean的Nexus S上,相机的行为正常,而Camera Zoom FX则会导致此错误。在运行ICS的Archos G9平板电脑上,相机和Zoom FX都会导致错误。
我已经逐步检查了代码,但找不到重新启动调用的来源。当我在第二个(和后续的)onCreate()调用中停止调试器时,在调用堆栈中有一个ActivityThread.handleRelaunchActivity()调用。它的Intent没有太多信息:动作为null,类是AcceptPhoto。 mFlags具有603979776值,我不知道如何将其转换为实际的意图标记。
但是,这种古怪并不止于此。在我的平板电脑上,我第一次拍照时,应用程序很好。如果我尝试拍第二张照片,屏幕会变得疯狂。如果我没有拍摄秒图片,而是返回上一个屏幕,那么在我打开新活动之前一切正常。无论从哪里开始,如果我一直返回到根活动并开始一个新的活动,它就会开始闪烁。我会尝试发布一些代码,但我怀疑这个错误不是由我的代码引起的,而是我在底层的Android代码中触发了一些东西。我希望的是,也许有人可以指出我正确的方向来找到解决这个bug的方法。任何事都有帮助,所以我感谢你的任何想法!
用于打开相机的代码(使用实用程序类在AcceptPhoto.onCreate()中调用):
private void openCamera(Context context) {
Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File tempFile = getTempFile(context);
try {
if (tempFile != null) {
pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
((Activity) context).startActivityForResult(pictureIntent, GET_ITEM_PHOTO);
} else {
Toast.makeText(context, "Could not create temp file", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(context, "Error opening camera " + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
用于显示图片的代码,在AcceptPhoto.onActivityResult()中调用:
private void displayPhoto() {
if (cameraUtils == null) {
cameraUtils = new CameraUtil();
}
previewImageView.setImageDrawable(null);
File tempFile = cameraUtils.getTempFile(this);
int rotation = 0;
try {
ExifInterface exif = new ExifInterface(tempFile.getPath());
String orientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
Log.i("SPRING", "Photo orientation " + orientation);
rotation = getBitmapRotation(Integer.valueOf(orientation));
Log.i("SPRING", "The image needs to be rotated by " + (rotation) + " degrees");
} catch (IOException e1) {
e1.printStackTrace();
}
try {
previewBitmap = BitmapEncoderUtil.loadPrescaledBitmap(tempFile);
if (rotation != 0) {
Matrix rotationMatrix = new Matrix();
rotationMatrix.postRotate(rotation);
int w = previewBitmap.getWidth();
int h = previewBitmap.getHeight();
Bitmap rotatedBitmap = Bitmap.createBitmap(previewBitmap, 0, 0, w, h, rotationMatrix, false);
previewBitmap = rotatedBitmap;
}
previewImageView.setImageBitmap(previewBitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
实用程序类中用于创建/检索相机保存照片的文件的方法:
public File getTempFile(Context context) {
String externalStorageStateString = Environment.getExternalStorageState();
File cacheDirectory;
// try to save in external storage
if (externalStorageStateString.equals(Environment.MEDIA_MOUNTED)) {
cacheDirectory = context.getExternalCacheDir();
} else {
// save in internal storage
cacheDirectory = context.getCacheDir();
}
File tempSnapshotFile = new File(cacheDirectory, MissionOtherActivity.ITEM_SNAPSHOT_PATH);
// make sure the file exists, possible fix for the camera bug
try {
if (tempSnapshotFile.exists() == false) {
tempSnapshotFile.getParentFile().mkdirs();
tempSnapshotFile.createNewFile();
}
} catch (IOException e) {
Log.e("SPRING", "Could not create file.", e);
}
return tempSnapshotFile;
}
答案 0 :(得分:18)
经过大量调查后,似乎重新启动的呼叫来自onConfigurationChanged。我还是没弄明白为什么,但至少我知道该避免什么。
它解释了为什么有些相机触发了这个错误而其他相机没有:一些相机使用与我的应用程序相同的配置,其他相机没有。
编辑:我在其他调查后发现我在扩展的Application类中有一个错误。在onConfigurationChanged方法中,我通过强制某个语言环境来更改配置。这触发了一个新的onConfigurationChanged()调用,它导致了一个无限循环和随后的屏幕创建/销毁序列。我不知道为什么我把这些代码放在onConfigurationChanged()方法中,但我想你必须忍受才能学习:)