androidxmlkotlindebuggingandroid-debug

What could be the cause of this error? (Kotlin) (AndroidRuntime: FATAL EXCEPTION: main)


I got the following error while debugging my app:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.studycountdowntimer, PID: 16161
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.studycountdowntimer/com.example.studycountdowntimer.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3395)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3651)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2104)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:236)
        at android.app.ActivityThread.main(ActivityThread.java:7861)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
        at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:184)
        at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:174)
        at android.content.Context.obtainStyledAttributes(Context.java:753)
        at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:842)
        at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:809)
        at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:633)
        at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:259)
        at com.example.studycountdowntimer.MainActivity.<init>(MainActivity.kt:19)
        at java.lang.Class.newInstance(Native Method)
        at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
        at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1254)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3383)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3651) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2104) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:236) 
        at android.app.ActivityThread.main(ActivityThread.java:7861) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967) 
I/Process: Sending signal. PID: 16161 SIG: 9
Disconnected from the target VM, address: 'localhost:58274', transport: 'socket'

Here is the activity_main.xml code:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#673AB7"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/inputTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@null"
        android:hint="@string/inputTime"
        android:importantForAutofill="no"
        android:inputType="number"
        android:minWidth="48dp"
        android:minHeight="48dp"
        android:textAlignment="center"
        android:textColor="#FFFFFF"
        android:textColorHighlight="#AE81FF"
        android:textColorHint="#7AFFFFFF"
        android:textColorLink="@null"
        android:textCursorDrawable="@android:drawable/btn_default"
        android:textSize="44sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.35"
        tools:ignore="TextContrastCheck,DuplicateSpeakableTextCheck" />

    <TextView
        android:id="@+id/showTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minWidth="48dp"
        android:minHeight="48dp"
        android:textAlignment="center"
        android:textColor="#FFFFFF"
        android:textColorHighlight="#AE81FF"
        android:textSize="44sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.35"
        tools:text="00:00:00" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/startButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="96dp"
        android:layout_marginTop="44dp"
        android:clickable="true"
        android:contentDescription="@string/startButton"
        android:focusable="true"
        android:tint="#FFFFFF"
        app:backgroundTint="#EE7745CF"
        app:fabCustomSize="80dp"
        app:fabSize="auto"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/inputTime"
        app:maxImageSize="35dp"
        app:srcCompat="@android:drawable/ic_media_play"
        tools:ignore="SpeakableTextPresentCheck,ImageContrastCheck,DuplicateClickableBoundsCheck" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/pauseButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="96dp"
        android:layout_marginTop="44dp"
        android:clickable="true"
        android:contentDescription="@string/pauseButton"
        android:focusable="true"
        android:tint="#FFFFFF"
        android:visibility="invisible"
        app:backgroundTint="#EE7745CF"
        app:fabCustomSize="80dp"
        app:fabSize="auto"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/inputTime"
        app:maxImageSize="35dp"
        app:srcCompat="@android:drawable/ic_media_pause"
        tools:ignore="ImageContrastCheck" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/stopButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="45dp"
        android:layout_marginEnd="96dp"
        android:clickable="true"
        android:contentDescription="@string/stopButton"
        android:focusable="true"
        android:tint="#FFFFFF"
        app:backgroundTint="#EE7745CF"
        app:fabCustomSize="80dp"
        app:fabSize="auto"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/inputTime"
        app:maxImageSize="35dp"
        app:srcCompat="@drawable/ic_media_stop"
        tools:ignore="SpeakableTextPresentCheck" />

</androidx.constraintlayout.widget.ConstraintLayout>

and the MainActivity.kt:

package com.example.studycountdowntimer

import android.annotation.SuppressLint
import android.os.Bundle
import android.os.CountDownTimer
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private var startMilliseconds = 60000L

    private lateinit var cdTimer: CountDownTimer
    private var onRun: Boolean = false
    var timeInMilliseconds = 0L

    private val timeInput: EditText = findViewById(R.id.inputTime)
    private val timeShow: TextView = findViewById(R.id.showTime)
    private val buttonStart: Button = findViewById(R.id.startButton)
    private val buttonPause: Button = findViewById(R.id.pauseButton)
    private val buttonStop: Button = findViewById(R.id.stopButton)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        buttonStart.setOnClickListener {
            if (onRun) {
                pauseTime()
                buttonPause.visibility = View.VISIBLE

            } else {
                val time  = timeInput.text.toString()
                timeInMilliseconds = time.toLong() *60000L
                startTime(timeInMilliseconds)
            }
        }

        buttonStop.setOnClickListener {
            stopTime()
        }

    }

    private fun pauseTime() {

        cdTimer.cancel()
        onRun = false

    }

    private fun startTime(timeInSeconds: Long) {
        cdTimer = object : CountDownTimer(timeInSeconds, 1000) {
            @SuppressLint("SetTextI18n")
            override fun onFinish() {
                timeShow.text = "You did it!"
            }

            override fun onTick(p0: Long) {
                timeInMilliseconds = p0
                updateTextUI()
            }
        }
        cdTimer.start()

        onRun = true
        buttonStart.visibility = View.INVISIBLE

    }

    private fun stopTime() {
        timeInMilliseconds = startMilliseconds
        updateTextUI()
    }

    @SuppressLint("SetTextI18n")
    private fun updateTextUI() {
        val minutes = (timeInMilliseconds / 1000) / 60
        val seconds = (timeInMilliseconds / 1000) % 60
        val hours = minutes / 60

        timeShow.text = "$hours:$minutes:$seconds"
    }
}

What could possibly be happening? Thanks in advance!


Solution

  • I copied the code and debugged it quickly. I found the reason and fixed the crash.

    Reproduced the crash

    crash in mainactivity

    The reason

    As Alex said that the method of findViewById is called before onCreate()

    Solution

    Using lateinit var to lazy initiate those properties.

        private lateinit var timeInput: EditText
        private lateinit var timeShow: TextView
        private lateinit var buttonStart: FloatingActionButton
        private lateinit var buttonPause: FloatingActionButton
        private lateinit var buttonStop: FloatingActionButton
    
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            timeInput = findViewById(R.id.inputTime)
            timeShow = findViewById(R.id.showTime)
            buttonStart = findViewById(R.id.startButton)
            buttonPause = findViewById(R.id.pauseButton)
            buttonStop = findViewById(R.id.stopButton)
    ...
    }
    

    Note: there are others crashes, for an instance, private lateinit var buttonStart: Button will cause this crash:

    crash in Button

    We need to know the mean of this crash from the crash log, so I changed the Button to FloatingActionButton

    Enjoy programming.