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.(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!
CodePudding user response:
I copied the code and debugged it quickly. I found the reason and fixed the crash.
Reproduced the crash
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:
We need to know the mean of this crash from the crash log, so I changed the Button
to FloatingActionButton
Enjoy programming.