Android开发,用Kotlin语言。实现一个文件保存的功能,部分代码如下: override fun onDestroy() { super.onDestroy() val editText_2: EditText = findViewById(R.id.fileStoreEdit2) val inputText_2 = editText_2.text.toString() save_2(inputText_2) } private fun save_2(inputText: String) { try { val file = File(getExternalFilesDir(null), "testdata02") val writer = BufferedWriter(FileWriter(file)) writer.use { it.write(inputText) } } catch (e: IOException) { e.printStackTrace() } }
执行时,程序报错: FATAL EXCEPTION: main Process: com.example.activitytest, PID: 15501 java.lang.RuntimeException: Unable to destroy activity {com.example.activitytest/com.example.activitytest.FileStoreActivity}: java.lang.IllegalStateException: FragmentManager has been destroyed at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:5889) at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:5919) at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:44) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:190) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2624) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:219) at android.app.ActivityThread.main(ActivityThread.java:8679) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109) Caused by: java.lang.IllegalStateException: FragmentManager has been destroyed at androidx.fragment.app.FragmentManager.ensureExecReady(FragmentManager.java:1936) at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1996) at androidx.fragment.app.FragmentManager.dispatchDestroy(FragmentManager.java:3105) at androidx.fragment.app.FragmentController.dispatchDestroy(FragmentController.java:334) at androidx.fragment.app.FragmentActivity.onDestroy(FragmentActivity.java:330) at androidx.appcompat.app.AppCompatActivity.onDestroy(AppCompatActivity.java:283) at com.example.activitytest.BaseActivityClass.onDestroy(BaseActivityClass.kt:38) at com.example.activitytest.FileStoreActivity.onDestroy(FileStoreActivity.kt:39) at android.app.Activity.performDestroy(Activity.java:8478) at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1355) at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:5874) at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:5919) at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:44) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:190) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2624) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:219) at android.app.ActivityThread.main(ActivityThread.java:8679) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)
请排除问题,并修复代码
从错误日志来看,问题出在 onDestroy
方法中调用 findViewById
导致的 IllegalStateException
。在 onDestroy
方法中,Activity 的视图层次结构可能已经被销毁,因此调用 findViewById
可能会导致异常。
为了修复这个问题,可以在 onPause
或 onStop
方法中保存数据,而不是在 onDestroy
中。这样可以确保在视图层次结构被销毁之前完成数据保存。
以下是修复后的代码:
override fun onPause() {
super.onPause()
val editText_2: EditText = findViewById(R.id.fileStoreEdit2)
val inputText_2 = editText_2.text.toString()
save_2(inputText_2)
}
private fun save_2(inputText: String) {
try {
val file = File(getExternalFilesDir(null), "testdata02")
val writer = BufferedWriter(FileWriter(file))
writer.use {
it.write(inputText)
}
} catch (e: IOException) {
e.printStackTrace()
}
}
在这个修复中,我们将数据保存的逻辑从 onDestroy
移动到了 onPause
方法中。onPause
方法在 Activity 进入后台时调用,此时视图层次结构仍然存在,因此可以安全地调用 findViewById
。
此外,确保在 AndroidManifest.xml
中声明了写入外部存储的权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
如果你的应用目标 SDK 版本是 23 或更高版本,还需要在运行时请求权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_WRITE_STORAGE)
}
这样可以确保在保存文件时拥有必要的权限。