【问题标题】:Fatal signal 11 (SIGSEGV), code 128, fault addr 0x0 in tid 12680 when using Gson.fromJson使用 Gson.fromJson 时,致命信号 11 (SIGSEGV),代码 128,tid 12680 中的故障地址 0x0
【发布时间】:2020-02-12 09:42:09
【问题描述】:

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

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】:

    造成这种情况的根本原因是VideoDetails 数据类中的位图。显然,Gson 不能处理位图。我决定为VideoDetails 创建一个自定义TypeAdapter,而不是删除位图。这样我就不必更改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"
        }
    }
    

    位图被简单地转换为IntArray,然后包含位图中每个像素的 Int 值以及位图的宽度和高度作为该数组的最后两个条目。然后将此IntArray 转换为Json。将其转换回位图只是将这个过程颠倒过来。

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

        private val gson = GsonBuilder()
                .registerTypeAdapter(VideoDetails::class.java, VideoDetailsTypeAdapter())
                .create()
    

    【讨论】:

      猜你喜欢
      • 2016-05-17
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 2016-09-25
      • 2017-01-05
      • 2017-11-05
      • 2018-03-29
      • 1970-01-01
      相关资源
      最近更新 更多