Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在AsyncTask内压缩位图时引发异常。任务未停止执行_Android_Kotlin - Fatal编程技术网

Android 在AsyncTask内压缩位图时引发异常。任务未停止执行

Android 在AsyncTask内压缩位图时引发异常。任务未停止执行,android,kotlin,Android,Kotlin,我有一个用Kotlin编写的AsyncTask,它处理位图并将其存储到内部存储器中的文件中。我的手机没有新位图的可用空间,因此在写入过程中,会引发IOException,这会导致应用程序崩溃 这是我的doInBackground()函数: override fun doInBackground(vararg params: Int?): Exception? { if(params[0] == null) throw IllegalArgumentException();

我有一个用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")

    }
这应该会崩溃,或者至少会返回一个带有“Write failed”消息的异常,但它永远不会返回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

位图类故意不在失败时引发异常

文档中没有列出此方法的例外情况,而是将预期返回值列为:

如果成功压缩到指定流,则返回:布尔值true

这就是为什么您会看到您的日志输出行“fout is closed”,因为没有抛出异常,也没有检查布尔结果

调用
compress()
的代码行需要检查布尔结果:

if (!source.compress(Bitmap.CompressFormat.PNG, quality, fout)) {
    throw IOException("compression failure")
}

什么输出“----write抛出异常”?如果代码返回类型为
exception
的内容而不是抛出异常(这会导致在检索AyncTask的结果时抛出
ExecutionException
),这也有点令人困惑,你可以返回一个
PhotoEditResult
类或枚举。在谷歌搜索之后,输出来自android用于图像解码的SKIA库。我同意这有点混乱,但我预计它会崩溃,不会返回任何东西。我最初的想法是捕获
IOException
并将其返回,但这也不起作用。这看起来很可疑:
原因:libcore.io.ErrnoException:write failed:ENOSPC(设备上没有剩余空间)
您的设备是否已满,因此无法写入文件?