【发布时间】:2016-09-09 16:23:19
【问题描述】:
我有一个用 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")
}
将文件写入位图的函数是:
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")
}
这应该会崩溃,或者至少会返回带有“写入失败”消息的异常,但它永远不会返回 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??
【问题讨论】:
-
什么输出“------- write throw an exception”?
-
看到代码返回
Exception类型的东西而不是抛出异常(这将导致在检索 AynscTask 的结果时抛出ExecutionException)也有点令人困惑,你可以返回PhotoEditResult类或枚举。 -
谷歌搜索后,输出来自android用于图像解码的SKIA库stackoverflow.com/questions/5751719/android-skia-image-decoding
-
我同意这有点令人困惑,但我希望它会崩溃并且根本不会返回任何东西。我最初的想法是捕获
IOException并将其作为结果返回,但这也不起作用。 -
这看起来很可疑:
Caused by: libcore.io.ErrnoException: write failed: ENOSPC (No space left on device)您的设备是否已满,因此无法写入文件?