2017-01-13 69 views
0

我遇到了與cropImageView相關的事務過大異常問題。任何時候我使用cropImageView來裁剪圖像,然後使用意圖來更改活動,它會給我一個Transaction太大的異常。CropImageView交易過大異常

我繼續看到它可能是因爲我將太多的數據從一個活動傳遞到另一個活動,但即使當我在代碼中傳遞一個字節數組的代碼時,它仍然與事務崩潰大的例外。

這裏是我的代碼:

public class TestActivity extends AppCompatActivity { 

private CropImageView cropImageView; 
private Button cropImage; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_test); 

    cropImage = (Button) findViewById(R.id.cropImage); 
    cropImageView = (CropImageView) findViewById(R.id.cropImageView); 

    Intent intent = getIntent(); 
    byte[] bite = intent.getExtras().getByteArray("imageForCropping"); 

    Bitmap bitmap = getPhoto(bite); 

    cropImageView.setImageBitmap(bitmap); 

    cropImage.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Bitmap bit = cropImageView.getCroppedImage(); 
      byte[] byteArray = getBytes(bit); 
      Intent intent = new Intent(TestActivity.this, HomeScreenActivity.class); 
      intent.putExtra("croppedImage", byteArray); 
      TestActivity.this.startActivity(intent); 

     } 
    }); 



} 

public static Bitmap getPhoto(byte[] image) { 
    return BitmapFactory.decodeByteArray(image, 0, image.length); 

} 

public static byte[] getBytes(Bitmap image) { 
    ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    image.compress(Bitmap.CompressFormat.PNG, 100, stream); 
    return stream.toByteArray(); 
} 

} 

我試圖避免使用此意圖通過使用SQLite數據庫的字節數組傳遞,但它仍然與交易過大的異常崩潰。所以這導致我相信CropImageView導致了這個問題。

請讓我知道,如果你知道問題可能是什麼。

在此先感謝!

回答

1

這是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; 
} 
+0

你能解釋一下這個嗎?我對有關super.onSaveInstanceState()的部分有點困惑,並且還原了位圖。 @EpicPandaForce – meherrr

0

不要在意圖或任何地方傳遞圖像的字節。將其保存在磁盤上,僅傳遞URI,並從磁盤讀取圖像