這是cropImageView
中的一個錯誤,它嘗試在調用onSaveInstanceState()
時將圖像保存爲其自己的視圖狀態。
解決方法是將圖像保存到文件中,然後在調用super.onSaveInstanceState()
之前在裁剪圖像視圖上調用setImageBitmap(null)
,然後在需要時從文件中恢復圖像位圖。
編輯:好的,我會分享我的代碼,但它真的很hacky。我很高興,它的工作。另外,它是來自相機,所以我拍了照片,並獲得了位圖作爲一個字節數組。
請小心提醒。
@Override
public void onResume() {
if(cameraPresenter != null) {
cameraPresenter.onResume();
}
if(takenBitmap != null && !takenBitmap.isRecycled()) {
takenPhotoDisplay.setImageBitmap(takenBitmap);
}
}
@Override
public void onViewDestroyed(boolean removedByFlow) {
takenPhotoDisplay.setImageBitmap(null);
}
@Override // called before `Activity super.onSaveInstanceState()`
public void preSaveViewState(Bundle bundle) {
takenPhotoDisplay.setImageBitmap(null);
}
private byte[] takenPhoto;
private Bitmap takenBitmap;
private void restoreBitmap() {
try {
takenPhoto = readByteArrayFromFile("TEMP");
} catch(FileNotFoundException e) {
Log.e(TAG, "No bitmap found to restore");
} catch(IOException e) {
Log.e(TAG, "Could not read bitmap");
}
}
private byte[] readByteArrayFromFile(String fileName)
throws IOException {
Context context = CustomApplication.get();
byte[] result = null;
FileInputStream fileInputStream = null;
try {
fileInputStream = context.openFileInput(fileName);
result = IOUtils.toByteArray(fileInputStream);
} catch(FileNotFoundException e) {
Log.e(TAG, "The file was not found [" + fileName + "]", e);
throw e;
} catch(IOException e) {
Log.e(TAG, "Unable to read data from stream [" + fileName + "]", e);
throw e;
} finally {
if(fileInputStream != null) {
try {
fileInputStream.close();
} catch(IOException e) {
Log.e(TAG, "Could not close.");
}
}
}
return result;
}
private void preserveBitmap() {
if(takenPhoto != null) {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = CustomApplication.get().openFileOutput("TEMP", Context.MODE_PRIVATE);
fileOutputStream.write(takenPhoto);
} catch(FileNotFoundException e) {
Log.e(TAG, "Could not open temp");
} catch(IOException e) {
Log.e(TAG, "Could not write temp");
} finally {
if(fileOutputStream != null) {
try {
fileOutputStream.close();
} catch(IOException e) {
Log.e(TAG, "Nobody cares!");
}
}
}
}
}
private void destroyCurrentBitmap() {
if(takenBitmap != null) {
takenPhotoDisplay.setImageBitmap(null);
takenBitmap.recycle();
takenBitmap = null;
takenPhoto = null;
Runtime.getRuntime().gc();
}
}
private void handleTakenPhoto(byte[] data) {
CameraView.this.takenPhoto = data;
if(takenPhoto != null) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bm = BitmapFactory.decodeByteArray(takenPhoto, 0, takenPhoto.length, options);
Log.d(TAG, "The Bitmap has width [" + bm.getWidth() + "] and height [" + bm.getHeight() + "]");
// Setting post rotate to 90
Matrix mtx = new Matrix();
Log.i(TAG, "CURRENT ROTATION ANGLE: [" + getRotationAngle() + "]");
// Rotating Bitmap
mtx.postRotate(getRotationAngle());
// Flipping bitmap
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(getActiveCameraId(), info);
if(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
mtx.postScale(-1, 1, bm.getWidth()/2, bm.getHeight()/2);
}
Runtime.getRuntime().gc();
Bitmap newBitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), mtx, true);
if(bm != newBitmap) {
bm.recycle();
bm = newBitmap; //yes, this is on purpose!
Runtime.getRuntime().gc();
} else {
Log.i(TAG, "The created bitmap is the same as the previous one.");
}
bm = newBitmap; //yes, this is on purpose!
takenBitmap = bm;
if(takenBitmap != null && !takenBitmap.isRecycled()) {
takenPhotoDisplay.setImageBitmap(takenBitmap);
} else {
Log.w(TAG, "The bitmap in [takenBitmap] is recycled!");
takenPhotoDisplay.setImageBitmap(null);
}
} else {
Log.w(TAG, "The taken photo is NULL.");
}
}
//IMAGE ROTATION FIX
public int getRotationAngle(int cameraId) {
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
Activity activity = ActivityUtils.getActivity(getContext());
WindowManager windowManager = activity.getWindowManager();
Display defaultDisplay = windowManager.getDefaultDisplay();
int rotation = defaultDisplay.getRotation();
int degrees = 0;
switch(rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
//if(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
// result = (info.orientation + degrees) % 360;
// result = (360 - result) % 360; // compensate the mirror
//} else { // back-facing
// result = (info.orientation - degrees + 360) % 360;
//}
if(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
result = (info.orientation - degrees + 540) % 360;
} else {
result = (info.orientation - degrees + 360) % 360;
}
} else {
result = (info.orientation - degrees + 360) % 360;
}
return result;
}
你能解釋一下這個嗎?我對有關super.onSaveInstanceState()的部分有點困惑,並且還原了位圖。 @EpicPandaForce – meherrr