【问题标题】:Android Studio Fatal Exception MAINAndroid Studio 致命异常主要
【发布时间】:2020-12-04 13:58:01
【问题描述】:

当我尝试启动我的程序时,我收到以下消息:

2020-12-04 14:45:19.691 12612-12612/de.thm.ap.recordclean E/AndroidRuntime: FATAL EXCEPTION: main
    Process: de.thm.ap.recordclean, PID: 12612
    java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
     Caused by: java.io.InvalidClassException: de.thm.ap.recordclean.model.Record; local class incompatible: stream classdesc serialVersionUID = -4375446896736906014, local class serialVersionUID = 9183845667872741158
        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:624)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1713)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1594)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1872)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1412)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
        at java.util.ArrayList.readObject(ArrayList.java:791)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1066)
        at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2013)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1899)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1412)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
        at de.thm.ap.recordclean.persistence.RecordDAO.initRecords(RecordDAO.kt:83)
        at de.thm.ap.recordclean.persistence.RecordDAO.<init>(RecordDAO.kt:11)
        at de.thm.ap.recordclean.persistence.RecordsActivity.onStart(RecordsActivity.kt:33)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1435)
        at android.app.Activity.performStart(Activity.java:8024)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3475)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

我的 RecordDao 看起来像这样:

class RecordDAO(private val ctx: Context) {
    private var nextId = 0
    private val records = initRecords()



    fun findAll(): List<Record> = records.toList()

    fun findById(id: Int): Record? {
        var record: Record? = Record()
        records.forEach { if( it.id== id) record = it }
        return record
    }





    /**
     * Ersetzt das übergebene [Record] Objekt mit einem bereits gespeicherten [Record] Objekt mit gleicher id.
     *
     * @param record
     * @return true = update ok, false = kein [Record] Objekt mit gleicher id im Speicher gefunden
     */
    fun update(record: Record): Boolean {
        var existing = false
        records.forEach {
            if(it.id == record.id){
                val index= records.indexOf(it)
                records[index] = record
                existing = true
            }
        }
        saveRecords()
        return existing
    }
    /**
     * Persistiert das übergebene [Record] Objekt und liefert die neue id zurück.
     * (Seiteneffekte: record.id = nextId; nextId += 1 )
     *
     * @param record
     * @return neue record id
     */
    fun persist(record: Record): Int {
        record.id = nextId
        records.add(record)
        saveRecords()
        return record.id!!

    }

    /**
     * Löscht das übergebene [Record] Objekt anhand der id aus dem Speicher.
     *
     * @param record
     * @return true = ok, false = kein [Record] Objekt mit gleicher id im Speicher gefunden
     */
    fun delete(record: Record): Boolean {
        var existing = false
        if(records.contains(record)){
            val index:Int = records.indexOf(record)
            records.removeAt(index)
            existing = true
            }
        saveRecords()
        return existing
        }


    private fun initRecords(): MutableList<Record> {
        val records = mutableListOf<Record>()
        val f = ctx.getFileStreamPath(FILE_NAME)
        if (f.exists()) {
            ctx.openFileInput(FILE_NAME).use { fin ->
                ObjectInputStream(fin).readObject().let { obj ->
                    records.addAll(obj as MutableList<Record>)
                    // init next id
                    if (records.size > 0) {
                        nextId += 1
                    }
                }

            }
        }
        return records;
    }

    private fun saveRecords() {
        ctx.openFileOutput(FILE_NAME, Context.MODE_PRIVATE)
                .use { ObjectOutputStream(it).writeObject(records) }
    }

    companion object {
        private const val FILE_NAME = "records.obj"
    }

我的 RecordsActivity 是这样的:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_records)

        this.recordListView.emptyView = recordListEmptyView


    }

    override fun onStart() {
        super.onStart()

        val outputRecords = RecordDAO(this).findAll().map {
            "${it.moduleName} ${it.moduleNum} (%${it.noteInProzent} ${it.creditPoints}crp)"
        }

        val allRecords = RecordDAO(this).findAll()

        val adapter = ArrayAdapter(this,android.R.layout.simple_list_item_activated_1,outputRecords)

        this.recordListView.adapter = adapter

        recordListView.setOnItemClickListener { parent, view, position, id ->
            val record: Record = allRecords[position]
            intent = Intent(this,EditFormActivity::class.java)
            intent.putExtra("record",record)
            startActivity(intent)
        }

        with(recordListView) {
            val checkedRecords = ArrayList<Record>()
            choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL
            setMultiChoiceModeListener(object: AbsListView.MultiChoiceModeListener {

                override fun onItemCheckedStateChanged(mode: ActionMode?, position: Int, id: Long, checked: Boolean) {
                    if(checked) checkedRecords.add(allRecords[position])
                }

                override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
                    val menuInflater = menuInflater
                    menuInflater.inflate(R.menu.list_view_contextual_menu,menu)
                    return true
                }

                override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
                    return false
                }

                override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {


                        //val emailSubject = "Meine Leistungen $size "
                        return when(item.itemId) {
                            R.id.delete_item -> {
                                AlertDialog.Builder(this@RecordsActivity)
                                        .setTitle("Delete list items")
                                        .setMessage("Are you sure you want to delete the selected items?")
                                        .setNegativeButton("No",null)
                                        .setPositiveButton("Yes") { _:DialogInterface, _:Int ->
                                            checkedRecords.forEach {
                                                RecordDAO(this@RecordsActivity).delete(it)
                                            }
                                            val i = Intent(this@RecordsActivity,RecordsActivity::class.java)
                                            startActivity(i)

                                        }
                                        .show()

                                true

                            }







                            else ->  {  println("no")
                            true}
                    }
                }

                override fun onDestroyActionMode(mode: ActionMode?) {

                }


            })
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.records,menu)
        return true
    }

    fun count50s() : Int {
        var count = 0

        val records = RecordDAO(this).findAll()
        records.forEach{
            if(it.funfzigProzentGewichtung) count++
        }
        return count
    }

    fun countCrp() : Int {
        var crp = 0
        val records = RecordDAO(this).findAll()
        records.forEach {
            crp += it.creditPoints
        }
        return crp
    }

    fun getDurchschnitt() : Int {
        var value = 0
        var summe =  0

        val records = RecordDAO(this).findAll()
        records.forEach {
            summe += it.noteInProzent
        }

        value = summe / records.size
        return value
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        return when(item.itemId) {
            R.id.action_add -> {
                val i = Intent(this, RecordFormActivity::class.java)
                startActivity(i)
                true
            }

            R.id.action_stats -> {
                val size = RecordDAO(this).findAll().size
                val count = count50s()
                val crp = countCrp()
                val ziel = 180-crp
                val durchSchnitt = getDurchschnitt()
                val message =
                        """
                    Leistungen $size 
                    50% Leistungen $count
                    Summe Crp $crp
                    Crp bis Ziel $ziel
                    Durchschnitt  $durchSchnitt
            
            
                """
                AlertDialog.Builder(this)
                        .setTitle("Statistik")
                        .setMessage(message)
                        .show()
                true
            }

            else -> super.onOptionsItemSelected(item)
        }

该程序之前已启动,我不太确定我更改了什么,因此它不再运行。我在玩 size 变量,但我想我把它改回原来的样子,我删除了表单 xml 文件中一个未使用的 TextView,就是这样我想如果我改变了其他东西,我就记不起来了

编辑:记录类

package de.thm.ap.recordclean.model

import java.io.Serializable


data class Record(var moduleName:String = "Betriebssysteme", var moduleNum: String = "CS2033",
                  var semester:Int = 2000, var creditPoints:Int = 6,
                  var noteInProzent:Int = 50,
                  var funfzigProzentGewichtung:Boolean = true) : Serializable {

    var id: Int? = null
}

【问题讨论】:

  • 您发布的课程似乎与错误中的课程不匹配。这条线似乎很重要。引起:java.io.InvalidClassException:de.thm.ap.recordclean.model.Record;本地类不兼容:stream classdesc serialVersionUID = -4375446896736906014,本地类serialVersionUID = 9183845667872741158 但我不知道recordclean是什么。
  • 也发布了我的 Record 课程

标签: android kotlin android-intent


【解决方案1】:

我通过更改保存项目的对象的名称解决了这个问题,但不太清楚它为什么会起作用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-03
    相关资源
    最近更新 更多