【发布时间】:2020-12-25 21:53:11
【问题描述】:
当活动或片段被销毁时,我想编写一个 1-10MB 的大文件。因为我想在用户关闭应用程序时存储文件,所以我必须在 onPause() 方法中执行此操作。我使用 DataOutputStream 因为它有编写不同类型的方法:Integer、Float、ByteArray 等等。
假设我需要编写一个大文件,这需要 2-3 秒。 onPause() 方法中的代码在主线程上执行。假设我使用 Thread.sleep(6000) 将线程冻结 6 秒以模拟线程工作。如果用户尝试返回应用程序,应用程序在这 6 秒内没有响应,因为所有工作都在主线程中完成。
如果我启动一个在单独的线程上运行任务的 AsyncTask 并在那里写入文件,那么冻结 UI 的问题就解决了。但据我所知,如果任务耗时6s,并且应用程序在线程完成工作之前就被销毁,内存泄漏问题很大!
所以我的问题是当用户即将关闭应用程序并防止内存泄漏时,如何在单独的线程上编写一个大文件??? 以下是在主线程上编写所有内容的示例代码:
override fun onStop() {
// code is run in the main thread
saveFile(context!!, "test", "testFile.txt")
}
fun saveFile(context: Context, fileDirectory: String, fileName: String) {
// path to /data/data/yourAppName/app_data/imageDir
val directory: File = context.getDir(fileDirectory, Context.MODE_PRIVATE)
val file = File(directory, fileName)
val fileOutputStream: FileOutputStream
try {
fileOutputStream = FileOutputStream(file)
val dataOutputStream = DataOutputStream(fileOutputStream)
dataOutputStream.writeInt(11) // write integer
dataOutputStream.writeFloat(1.8f) // write float
dataOutputStream.write(byteArrayOf(1, 33, 124, 41)) // write byte array
dataOutputStream.flush()
dataOutputStream.close()
fileOutputStream.flush()
fileOutputStream.close()
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
因为我需要上下文来生成文件,并且如果活动在线程完成工作之前被破坏,这将导致内存泄漏。如果我将上下文包装在 WeakReference 中,是否可以保护它免受内存泄漏?即使活动/片段被破坏,线程也会完成它的工作吗??
下面是使用 AsyncTask 的示例,并将上下文包装在 WeakReference 中!
class SaveFile(context: Context, var fileDirectory: String, var fileName: String) : AsyncTask<Void, Void, Int>() {
private var contextWrapper: WeakReference<ContextWrapper>
init {
val contextWrapper = ContextWrapper(context)
this.contextWrapper = WeakReference(contextWrapper)
}
override fun doInBackground(vararg params: Void): Int {
val directory: File = contextWrapper.get()!!.getDir(fileDirectory, Context.MODE_PRIVATE)
val file = File(directory, fileName)
val fileOutputStream: FileOutputStream
try {
fileOutputStream = FileOutputStream(file)
val dataOutputStream = DataOutputStream(fileOutputStream)
dataOutputStream.writeInt(11) // write integer
dataOutputStream.writeFloat(1.8f) // write float
dataOutputStream.write(byteArrayOf(1, 33, 124, 41)) // write byte array
dataOutputStream.flush()
dataOutputStream.close()
fileOutputStream.flush()
fileOutputStream.close()
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
return 0
}
}
【问题讨论】:
-
这是您使用服务的地方。在
onPause或onDestroy上启动服务。 -
所以我应该使用 IntentService 向用户显示他的工作正在被保存的消息。
-
通知可能会更好。
-
使用线程而不是 AsyncTask。但是为什么有些内存泄漏会困扰你呢?
-
@blackapps 内存泄漏应始终被视为严重问题。