在压缩AsyncTask中的位图时引发的exception不会停止执行
我有一个写在Kotlin的AsyncTask
处理一个位图,并将其存储到内部存储的文件。 我的手机没有可用空间来存放新的位图,所以在写入的时候抛出了IOException,这会导致应用程序崩溃。
这是我的doInBackground()
函数:
override fun doInBackground(vararg params: Int?): Exception? { if(params[0] == null) throw IllegalArgumentException(); Log.d("PhotoEditTask", "start") var bitmap : Bitmap? = null val degrees = if(params.size == 0) 0 else params[0] ?: 0 bitmap = BitmapProcessing.getBitmapFromUri(sourceUri, resolver) if (bitmap != null) { bitmap = BitmapProcessing.rotateBitmap(bitmap, degrees) var destFile = File(destPath) destFile.delete() BitmapFile.saveBitmapToFile(bitmap, destFile, 85) Log.d("PhotoEditTask", "save successfull!") return null } bitmap?.recycle() return Exception("Write failed") }
将文件写入Bitmap的函数是:
fun saveBitmapToFile(source: Bitmap, dest: File, quality: Int) { var fout : FileOutputStream? = null fout = FileOutputStream(dest) source.compress(Bitmap.CompressFormat.PNG, quality, fout) fout.flush() fout.close() Log.d("BitmapProcessing", "fout is closed") }
这应该会崩溃,或者至少用“写入失败”消息返回一个exception,但是它不应该返回null,因为我的电话不能写入文件。 然而,日志显示,否则:
09-09 12:16:40.824 26074-26805/com.criptext.uisample D/skia: jpeg_decoder finish successfully, L:1881!!! 09-09 12:16:40.833 26074-26805/com.criptext.uisample W/System.err: java.io.IOException: write failed: ENOSPC (No space left on device) 09-09 12:16:40.836 26074-26805/com.criptext.uisample W/System.err: at libcore.io.IoBridge.write(IoBridge.java:499) 09-09 12:16:40.836 26074-26805/com.criptext.uisample W/System.err: at java.io.FileOutputStream.write(FileOutputStream.java:187) 09-09 12:16:40.837 26074-26805/com.criptext.uisample W/System.err: at android.graphics.Bitmap.nativeCompress(Native Method) 09-09 12:16:40.837 26074-26805/com.criptext.uisample W/System.err: at android.graphics.Bitmap.compress(Bitmap.java:1013) 09-09 12:16:40.837 26074-26805/com.criptext.uisample W/System.err: at com.criptext.monkeykitui.util.BitmapFile.saveBitmapToFile(BitmapFile.java:18) 09-09 12:16:40.837 26074-26805/com.criptext.uisample W/System.err: at com.criptext.monkeykitui.input.photoEditor.PhotoEditTask.doInBackground(PhotoEditTask.kt:42) 09-09 12:16:40.838 26074-26805/com.criptext.uisample W/System.err: at com.criptext.monkeykitui.input.photoEditor.PhotoEditTask.doInBackground(PhotoEditTask.kt:17) 09-09 12:16:40.838 26074-26805/com.criptext.uisample W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:288) 09-09 12:16:40.838 26074-26805/com.criptext.uisample W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237) 09-09 12:16:40.839 26074-26805/com.criptext.uisample W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 09-09 12:16:40.840 26074-26805/com.criptext.uisample W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 09-09 12:16:40.840 26074-26805/com.criptext.uisample W/System.err: at java.lang.Thread.run(Thread.java:848) 09-09 12:16:40.840 26074-26805/com.criptext.uisample W/System.err: Caused by: libcore.io.ErrnoException: write failed: ENOSPC (No space left on device) 09-09 12:16:40.842 26074-26805/com.criptext.uisample W/System.err: at libcore.io.Posix.writeBytes(Native Method) 09-09 12:16:40.842 26074-26805/com.criptext.uisample W/System.err: at libcore.io.Posix.write(Posix.java:202) 09-09 12:16:40.843 26074-26805/com.criptext.uisample W/System.err: at libcore.io.BlockGuardOs.write(BlockGuardOs.java:197) 09-09 12:16:40.843 26074-26805/com.criptext.uisample W/System.err: at libcore.io.IoBridge.write(IoBridge.java:494) 09-09 12:16:40.843 26074-26805/com.criptext.uisample W/System.err: ... 11 more 09-09 12:16:40.843 26074-26805/com.criptext.uisample D/skia: ------- write threw an exception 09-09 12:16:40.844 26074-26805/com.criptext.uisample D/BitmapToFile: fout is closed 09-09 12:16:40.844 26074-26805/com.criptext.uisample D/PhotoEditTask: save successfull! 09-09 12:16:40.844 26074-26074/com.criptext.uisample D/PhotoEditTask: result: null
根据日志, IOException
被抛出并被捕获,但执行永远不会中断,所以它总是返回null。 到底是怎么回事? 我怎样才能处理IOException
?
Bitmap
类的compress()
方法故意不会在失败时抛出exception。
该文档没有列出此方法的例外情况,而是将预期的返回值列为:
返回:boolean如果成功压缩到指定的流,则返回true。
这就是为什么你看到你的日志输出行“fout被关闭”,因为没有抛出exception,并且没有检查布尔结果。
调用compress()
的代码行需要检查布尔结果:
if (!source.compress(Bitmap.CompressFormat.PNG, quality, fout)) { throw IOException("compression failure") }
- 与标志的kotlin startactivity
- kotlin coroutine抛出java.lang.IllegalStateException:已经恢复,但得到了值的位置
- msg:在数据绑定中找不到属性“android:text”的值types为java.lang.String的getter?
- 如何访问CalendarProvider与房间?
- 将RealmObject类转换为Kotlin时编译时错误
- 什么是Kotlin中的generateStubs配置?
- 不能用Dagger2提供合格的字符串
- Android号码选择器键盘types
- Gradle错误升级到Android Studio 3.0 Beta 1