You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio待办清单编辑器Binder空指针致Toast异常求助

问题:待办清单应用笔记编辑器Toast报错「Expecting binder but got null!」

报错信息

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 18:32:21