为什么变量即使创建后也没有初始化?

时间:2020-08-04 13:21:47

标签: android kotlin

我真的不明白为什么未初始化logFile(and loggingProcess)。日志记录表明该文件存在,并且在创建Activity时调用了createLogFile()方法,但是当我尝试从Activity(使用uploadLogs()SandboxApp().uploadLogs()时,它将引发异常< / p>

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)
        }
    }

1 个答案:

答案 0 :(得分:1)

您不应该自己创建应用类SandboxApp的实例,它是由系统完成的。要访问SandboxApp的实例,可以使用ctx.applicationContext属性:

val app = context.applicationContext as SandboxApp
app.uploadLogs()

因此,在OnClickListener中,它将类似于以下内容:

buttonSend.setOnClickListener {
    val app = applicationContext as SandboxApp
    app.uploadLogs()
}