私は、生のイメージを取得し、非同期に処理し、ユーザーに処理されたイメージを見せるように設計されたコードを持っています。画像処理によってOutOfMemoryエラーが発生することがあります。その場合、そのデバイスにメモリが不足していることをユーザーに通知したい場合があります。IllegalStateException OutOfMemoryExceptionを使用してonError()を呼び出すとき
しかし、エラーをキャッチしてサブスクライバに通知しようとするとクラッシュするようです。さらに、コードにブレークポイントを入れると、OutOfMemoryエラーがキャッチされ、subscriber.onError(e)
行がヒットしますが、onPhotoProcessingError(e)
には決して到達しません。サブスクリプションが発生したのはここ
は次のとおりです。ここで
imageDelegate.cropBitmap(rawPhoto, cameraManager.getPictureRotationDegrees(), cameraManager.getCurrentCameraId() == Camera.CameraInfo.CAMERA_FACING_FRONT)
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Bitmap>() {
@Override
public void onNext(Bitmap bitmap)
{
onPhotoProcessed(bitmap);
}
@Override
public void onError(Throwable e)
{
onPhotoProcessingError(e);
}
@Override
public void onCompleted()
{
}
});
はのOutOfMemoryエラーをキャッチするコードです:ここでは
public Observable<Bitmap> cropBitmap(Bitmap rawPhoto, int rotation, boolean isFrontFacing)
{
return Observable.create(new Observable.OnSubscribe<Bitmap>()
{
@Override
public void call(Subscriber<? super Bitmap> subscriber)
{
try
{
// rotates the photo so that it's portrait and cuts off the
// bottom of the photo so that we have a square photo
Bitmap rotatedSquarePhoto = PhotoUtils.rotateAndTruncateBottomOfPictureIntoSquare(rawPhoto, rotation);
rawPhoto.recycle();
// we want to mirror the image to match what the user saw when taking a selfie
if (isFrontFacing)
{
rotatedSquarePhoto = PhotoUtils.reflectAboutYAxis(rotatedSquarePhoto);
}
subscriber.onNext(rotatedSquarePhoto);
}
catch (OutOfMemoryError e)
{
subscriber.onError(e);
}
}
});
}
は、クラッシュのスタックトレースです:
04-06 16:40:55.303 22729-22729/ E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.emersonboyd, PID: 22729
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 921612 byte allocation with 861608 free bytes and 841KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:879)
at android.graphics.Bitmap.createBitmap(Bitmap.java:856)
at android.graphics.Bitmap.createBitmap(Bitmap.java:787)
at com.emersonboyd.util.PhotoUtils.rotateAndTruncateBottomOfPictureIntoSquare(PhotoUtils.java:225)
at com.emersonboyd.delgate.ImageDelegate$2.call(ImageDelegate.java:124)
at com.emersonboyd.delgate.ImageDelegate$2.call(ImageDelegate.java:116)
at rx.Observable.unsafeSubscribe(Observable.java:8460)
at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker$1.call(EventLoopsScheduler.java:169)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
正しい方向で私を指す助けがあれば素晴らしいだろう。 OutOfMemoryError
をRxJava
で致命的なエラーとして考えられているので、
これは機能しました。ありがとうございました :):) –