Почему переменная не инициализируется, даже если она была создана? - PullRequest
0 голосов
/ 04 августа 2020

Я действительно не понимаю, почему logFile (и loggingProcess) не инициализируются. Logcat показывает, что файл существует и метод createLogFile() был вызван при создании Activity, но когда я пытаюсь выполнить uploadLogs() из Activity (используя 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: onCreate метод MainActivity, где вызывается 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 Ответ

1 голос
/ 04 августа 2020

Вы не должны создавать экземпляр своего класса приложения SandboxApp самостоятельно, это делает система. Чтобы получить доступ к экземпляру SandboxApp, вы можете использовать свойство ctx.applicationContext:

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

Таким образом, в OnClickListener он будет выглядеть следующим образом:

buttonSend.setOnClickListener {
    val app = applicationContext as SandboxApp
    app.uploadLogs()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...