android - 为什么即使创建了变量也没有初始化?
问题描述
我真的不明白为什么 logFile(和 loggingProcess)没有初始化。logcat 显示该文件存在并且createLogFile()
在创建 Activity 时调用了方法,但是当我尝试uploadLogs()
从 Activity(using SandboxApp().uploadLogs()
) 中调用它时会引发异常
class SandboxApp: Application(), MyCallbacks {
companion object {
@JvmField
val TAG = SandboxApp::class.java.simpleName
}
private lateinit var loggingProcess: Process
private lateinit var logFile: File
private lateinit var fileDirectory: File
private var isLogging = false
private val formatter = SimpleDateFormat("dd-MM-yyyy_HH-mm", Locale.getDefault())
private lateinit var workManager: WorkManager
override fun onCreate() {
super.onCreate()
workManager = WorkManager.getInstance(this)
registerActivityLifecycleCallbacks(this)
}
fun createLogFile() {
val currentTime = formatter.format(Calendar.getInstance().time)
val fileName = "logs-$currentTime.log"
fileDirectory = File(filesDir.absolutePath + File.separator + "sandboxLog")
fileDirectory.mkdirs()
Log.d(TAG, "FileDir exists? $fileDirectory, ${fileDirectory.exists()}")
logFile = File(fileDirectory, fileName)
logFile.createNewFile()
Log.d(TAG, "File exists? $logFile, ${logFile.exists()}")
}
fun startLogging() {
isLogging = true
loggingProcess = Runtime.getRuntime().exec("logcat -f $logFile")
}
private fun stopLogging() {
isLogging = false
loggingProcess.destroy()
}
fun uploadLogs() {
stopLogging()
val data = Data.Builder()
.putString("file path", logFile.absolutePath)
.build()
val request = OneTimeWorkRequest.Builder(LogsWorker::class.java)
.setInputData(data)
.build()
workManager.enqueue(request)
createLogFile()
startLogging()
}
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
super.onActivityCreated(activity, savedInstanceState)
Log.d(TAG, "onActivityCreated method")
createLogFile()
startLogging()
}
}
这是例外,对于 loggingProcess 变量也是如此
2020-08-04 15:55:51.338 8741-8741/com.example.sandboxlog E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sandboxlog, PID: 8741
kotlin.UninitializedPropertyAccessException: lateinit property logFile has not been initialized
at com.example.sandboxlog.SandboxApp.uploadLogs(SandboxApp.kt:66)
at com.example.sandboxlog.MainActivity$onCreate$2.onClick(MainActivity.kt:33)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
upd:MainActivity的onCreate方法,这里调用uploadLogs
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d(TAG, "MainActivity created")
Thread.setDefaultUncaughtExceptionHandler(CrashHandler())
button.setOnClickListener {
// creating an exception
RequestBody.create(MultipartBody.FORM, exceptionFile!!)
}
buttonSend.setOnClickListener {
SandboxApp().uploadLogs()
}
buttonSecondActivity.setOnClickListener {
Log.d(TAG, "Starting second activity")
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
}
}
解决方案
您不应该自己创建应用程序类的实例SandboxApp
,它是由系统完成的。要访问您的实例,SandboxApp
可以使用ctx.applicationContext
属性:
val app = context.applicationContext as SandboxApp
app.uploadLogs()
所以在OnClickListener
它看起来像下面这样:
buttonSend.setOnClickListener {
val app = applicationContext as SandboxApp
app.uploadLogs()
}
推荐阅读
- javascript - Chart.js 具有一个共同图例的多个图表
- salesforce - 如何在闪电网络组件数据表 URL 列中添加 onclick 功能
- python - Python 的 struct.Struct 对象是线程安全的吗?
- javascript - 如何对表单进行验证?
- javascript - 如何制作一个搜索属性值的搜索框,然后根据用户输入隐藏或显示元素?
- itext7 - iText PDF 使用 .getSplitRenderer 进行表格渲染器
- javascript - 如何使 JS 导入可写?
- django - 两个方向的多对多
- python - 用于运行带有参数的 Python 程序的 Docker 文件
- rest - 使用 file_get_contents 测试 Rest API