Android Studio待办清单编辑器Binder空指针致Toast异常求助
报错信息
Input channel object 'c753b7d Toast (client)' was disposed without first being removed with the input manager!
Toast already killed. pkg=com.example.assigment2 token=android.os.BinderProxy@3c3b57f
已尝试的解决方法
- 初始化非空值
- 调整Toast调用位置
问题原因
代码逻辑存在时序错误:saveNoteData()中先调用writeNotesToXml(),而该方法末尾执行了finish()直接销毁当前Activity。当writeNotesToXml()执行完毕返回saveNoteData()时,Activity已经被销毁,此时调用Toast.makeText(this, ...).show(),Toast依赖的Activity上下文已失效,从而触发报错。
解决方案
调整Toast显示时机与Activity销毁的顺序,确保Toast显示时Activity仍处于活跃状态。以下提供两种可行修改方案:
方案1:将finish()移至saveNoteData()中执行
修改saveNoteData()和writeNotesToXml()的逻辑,让saveNoteData()控制Activity销毁时机,确保Toast先显示:
public void saveNoteData(View view) { String title = editTextTitle.getText().toString(); String description = editTextDescription.getText().toString(); if (!title.isEmpty() && !description.isEmpty()) { Task task; if (noteId != -1 && noteId < notes.size()) { task = notes.get(noteId); task.setTitle(title); task.setDescription(description); task.setStatus(noteStatus); } else { task = new Task(title, description, noteStatus); notes.add(task); noteId = notes.indexOf(task); } writeNotesToXml(); Toast.makeText(this, "笔记已保存", Toast.LENGTH_SHORT).show(); // 在Toast显示后销毁Activity finish(); } else { Toast.makeText(this, "请输入标题和描述", Toast.LENGTH_SHORT).show(); } } private void writeNotesToXml() { try { File file = new File(getFilesDir(), "notes.xml"); FileOutputStream fos = new FileOutputStream(file); XmlSerializer xmlSerializer = Xml.newSerializer(); xmlSerializer.setOutput(fos, "UTF-8"); xmlSerializer.startDocument(null, Boolean.TRUE); xmlSerializer.startTag(null, "notes"); for (Task task : notes) { xmlSerializer.startTag(null, "note"); xmlSerializer.startTag(null, "title"); xmlSerializer.text(task.getTitle()); xmlSerializer.endTag(null, "title"); xmlSerializer.startTag(null, "description"); xmlSerializer.text(task.getDescription()); xmlSerializer.endTag(null, "description"); xmlSerializer.startTag(null, "status"); xmlSerializer.text(task.getStatus()); xmlSerializer.endTag(null, "status"); xmlSerializer.endTag(null, "note"); } xmlSerializer.endTag(null, "notes"); xmlSerializer.endDocument(); xmlSerializer.flush(); fos.close(); Log.d("note_editor", "笔记已保存到XML文件"); } catch (IOException e) { e.printStackTrace(); } // 创建返回给MainActivity的Intent,修正参数为实际输入内容 Intent resultIntent = new Intent(); resultIntent.putExtra("note_title", editTextTitle.getText().toString()); resultIntent.putExtra("note_description", editTextDescription.getText().toString()); setResult(RESULT_OK, resultIntent); // 移除原有的finish() }
方案2:在writeNotesToXml()内部先显示Toast再销毁
如果需要保留writeNotesToXml()内部的销毁逻辑,可将Toast移至该方法内finish()之前:
public void saveNoteData(View view) { String title = editTextTitle.getText().toString(); String description = editTextDescription.getText().toString(); if (!title.isEmpty() && !description.isEmpty()) { Task task; if (noteId != -1 && noteId < notes.size()) { task = notes.get(noteId); task.setTitle(title); task.setDescription(description); task.setStatus(noteStatus); } else { task = new Task(title, description, noteStatus); notes.add(task); noteId = notes.indexOf(task); } writeNotesToXml(); } else { Toast.makeText(this, "请输入标题和描述", Toast.LENGTH_SHORT).show(); } } private void writeNotesToXml() { try { // 原有XML写入逻辑保持不变 File file = new File(getFilesDir(), "notes.xml"); FileOutputStream fos = new FileOutputStream(file); XmlSerializer xmlSerializer = Xml.newSerializer(); xmlSerializer.setOutput(fos, "UTF-8"); xmlSerializer.startDocument(null, Boolean.TRUE); xmlSerializer.startTag(null, "notes"); for (Task task : notes) { xmlSerializer.startTag(null, "note"); xmlSerializer.startTag(null, "title"); xmlSerializer.text(task.getTitle()); xmlSerializer.endTag(null, "title"); xmlSerializer.startTag(null, "description"); xmlSerializer.text(task.getDescription()); xmlSerializer.endTag(null, "description"); xmlSerializer.startTag(null, "status"); xmlSerializer.text(task.getStatus()); xmlSerializer.endTag(null, "status"); xmlSerializer.endTag(null, "note"); } xmlSerializer.endTag(null, "notes"); xmlSerializer.endDocument(); xmlSerializer.flush(); fos.close(); Log.d("note_editor", "笔记已保存到XML文件"); } catch (IOException e) { e.printStackTrace(); } Intent resultIntent = new Intent(); resultIntent.putExtra("note_title", editTextTitle.getText().toString()); resultIntent.putExtra("note_description", editTextDescription.getText().toString()); setResult(RESULT_OK, resultIntent); // 先显示Toast再销毁Activity Toast.makeText(this, "笔记已保存", Toast.LENGTH_SHORT).show(); finish(); }
额外优化提示
原代码中writeNotesToXml()的Intent传递了固定字符串"title"和"description",已在修改方案中替换为实际输入内容,确保MainActivity能接收到正确的笔记数据。
内容的提问来源于stack exchange,提问作者Yvsoi

