致命信号11(SIGSEGV),代码128,使用Gson.fromJson时,tid 12680中的故障加法器0x0

问题描述 投票:1回答:1

我的应用程序崩溃,除了出现此错误外,没有任何堆栈跟踪:

A/libc: Fatal signal 11 (SIGSEGV), code 128, fault addr 0x0 in tid 12680 (dio.downloadapp)

经过一些故障排除后,我将其范围缩小到导致此错误的那一行:

val details = gson.fromJson(fileReader, VideoDetails::class.java)

它来自视图模型的方法:

private fun onVideoDetailsFetched() {
            try {
                val file = File(context.filesDir, QUEUE_VIDEO_DETAILS_FILE)
                val fileReader = FileReader(file)
                val details = gson.fromJson(fileReader, VideoDetails::class.java)
                videoDetails.send(details)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

该文件是通过WorkManager库中的Worker类的方法创建的:

    private fun VideoDetails.saveVideoDetails() {
        val json = gson.toJson(this)
        File(applicationContext.filesDir, VIDEO_DETAILS_FILE).writeText(json)
    }

VideoDetails只是具有一串字符串和一个位图的数据类:

data class VideoDetails(
        val filename: String? = null,
        val title: String? = null,
        val vcodec: String? = null,
        val acodec: String? = null,
        val duration: String? = null,
        val filesize: String? = null,
        val width: String? = null,
        val height: String? = null,
        val bitrate: String? = null,
        val framerate: String? = null,
        val encoder: String? = null,
        val encodedBy: String? = null,
        val date: String? = null,
        val creationTime: String? = null,
        val artist: String? = null,
        val album: String? = null,
        val albumArtist: String? = null,
        val track: String? = null,
        val genre: String? = null,
        val composer: String? = null,
        val performer: String? = null,
        val copyright: String? = null,
        val publisher: String? = null,
        val language: String? = null,
        var thumbnail: Bitmap? = null
)

奇怪的是,崩溃仅在第三次调用Gson.fromJson()时发生。前两次,效果很好。

有人知道为什么我会收到此错误吗?以及如何解决?

更新:

当我删除位图时,它似乎可以正常工作。现在,问题是如何存储位图并使之工作。

android kotlin gson android-bitmap
1个回答
0
投票

这的根本原因是VideoDetails数据类中的位图。显然,Gson无法处理位图。我决定不删除位图,而是为TypeAdapter创建一个自定义TypeAdapter。这样,我不必更改VideoDetails类,因此不必更改代码的许多部分。

完整代码:

VideoDetails

[位图只是简单地转换为class VideoDetailsTypeAdapter : TypeAdapter<VideoDetails?>() { override fun write(out: JsonWriter?, value: VideoDetails?) { value?.apply { out?.apply { beginObject() filename?.let { name(FILENAME).value(it) } title?.let { name(TITLE).value(it) } vcodec?.let { name(VCODEC).value(it) } acodec?.let { name(ACODEC).value(it) } duration?.let { name(DURATION).value(it) } filesize?.let { name(FILESIZE).value(it) } width?.let { name(WIDTH).value(it) } height?.let { name(HEIGHT).value(it) } bitrate?.let { name(BITRATE).value(it) } framerate?.let { name(FRAMERATE).value(it) } encoder?.let { name(ENCODER).value(it) } encodedBy?.let { name(ENCODED_BY).value(it) } date?.let { name(DATE).value(it) } creationTime?.let { name(CREATION_TIME).value(it) } artist?.let { name(ARTIST).value(it) } album?.let { name(ALBUM).value(it) } albumArtist?.let { name(ALBUM_ARTIST).value(it) } track?.let { name(TRACK).value(it) } genre?.let { name(GENRE).value(it) } composer?.let { name(COMPOSER).value(it) } performer?.let { name(PERFORMER).value(it) } copyright?.let { name(COPYRIGHT).value(it) } publisher?.let { name(PUBLISHER).value(it) } language?.let { name(LANGUAGE).value(it) } thumbnail?.let { name(THUMBNAIL).beginArray() val pixelInts = IntArray(it.width * it.height) it.getPixels(pixelInts, 0, it.width, 0, 0, it.width, it.height) val storeInts = IntArray(pixelInts.size + 2) pixelInts.copyInto(storeInts, 0, 0, pixelInts.size) storeInts[storeInts.size - 2] = it.width storeInts[storeInts.size - 1] = it.height for (int in storeInts) value(int) endArray() } endObject() } } } override fun read(`in`: JsonReader?): VideoDetails? { return `in`?.run { beginObject() val entries = Array<String?>(24) { null } var thumbnail: Bitmap? = null while (hasNext()) { when (nextName()) { FILENAME -> entries[0] = nextString() TITLE -> entries[1] = nextString() VCODEC -> entries[2] = nextString() ACODEC -> entries[3] = nextString() DURATION -> entries[4] = nextString() FILESIZE -> entries[5] = nextString() WIDTH -> entries[6] = nextString() HEIGHT -> entries[7] = nextString() BITRATE -> entries[8] = nextString() FRAMERATE -> entries[9] = nextString() ENCODER -> entries[10] = nextString() ENCODED_BY -> entries[11] = nextString() DATE -> entries[12] = nextString() CREATION_TIME -> entries[13] = nextString() ARTIST -> entries[14] = nextString() ALBUM -> entries[15] = nextString() ALBUM_ARTIST -> entries[16] = nextString() TRACK -> entries[17] = nextString() GENRE -> entries[18] = nextString() COMPOSER -> entries[19] = nextString() PERFORMER -> entries[20] = nextString() COPYRIGHT -> entries[21] = nextString() PUBLISHER -> entries[22] = nextString() LANGUAGE -> entries[23] = nextString() THUMBNAIL -> { beginArray() val intList = mutableListOf<Int>() while (hasNext()) intList.add(nextInt()) endArray() val storeInts = intList.toIntArray() val pixelInts = IntArray(storeInts.size - 2) storeInts.copyInto(pixelInts, 0, 0, storeInts.size - 2) val width = storeInts[storeInts.size - 2] val height = storeInts[storeInts.size - 1] thumbnail = Bitmap.createBitmap(pixelInts, width, height, Bitmap.Config.ARGB_8888) } } } endObject() VideoDetails( entries[0], entries[1], entries[2], entries[3], entries[4], entries[5], entries[6], entries[7], entries[8], entries[9], entries[10], entries[11], entries[12], entries[13], entries[14], entries[15], entries[16], entries[17], entries[18], entries[19], entries[20], entries[21], entries[22], entries[23], thumbnail ) } } companion object { const val FILENAME = "filename" const val TITLE = "title" const val VCODEC = "vcodec" const val ACODEC = "acodec" const val DURATION = "duration" const val FILESIZE = "filesize" const val WIDTH = "width" const val HEIGHT = "height" const val BITRATE = "bitrate" const val FRAMERATE = "framerate" const val ENCODER = "encoder" const val ENCODED_BY = "encodedBy" const val DATE = "date" const val CREATION_TIME = "creationTime" const val ARTIST = "artist" const val ALBUM = "album" const val ALBUM_ARTIST = "albumArtist" const val TRACK = "track" const val GENRE = "genre" const val COMPOSER = "composer" const val PERFORMER = "performer" const val COPYRIGHT = "copyright" const val PUBLISHER = "publisher" const val LANGUAGE = "language" const val THUMBNAIL = "thumbnail" } } ,然后它包含位图中每个像素的Int值以及位图的宽度和高度,作为此数组的最后两个条目。然后将此IntArray转换为IntArray。将其转换回Bitmap只需逆转此过程即可。

以下代码将自定义Json注册到TypeAdapter

Gson
© www.soinside.com 2019 - 2024. All rights reserved.