Android Studio kotlin app "keep stopping" 錯誤


package com.example.absolutelydumb
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.InputType
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
//sets var to some random number and asks for a guess, giving feedback on proximity to answer
class MainActivity : AppCompatActivity() {
private val startButton: Button = findViewById(R.id.startButton)
private val submitButton: Button = findViewById(R.id.submit)
private val instructionsText: TextView = findViewById(R.id.instructionView)
private val response: EditText = findViewById(R.id.answerInput)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val startText: String = getString(R.string.startText)
startButton.text = startText
//TODO("Add autofillHints")
startButton.setOnClickListener {
numberGuess()
}
//TODO("Set text back to start after guessing is done")
}
fun numberGuess() {
response.inputType = InputType.TYPE_CLASS_NUMBER
val clickText: String = getString(R.string.clickText)
startButton.text = clickText
//TODO("Add autofillHints")
instructionsText.text = getString(R.string.instructions)
val randomNumber: Int = rand(0,10)
submitButton.setOnClickListener {
val responseText = Integer.parseInt(answerInput.text.toString())
if(responseText == randomNumber) {
instructionsText.text = getString(R.string.correctGuess)
} else {
instructionsText.text = getString(R.string.badGuess)
}
}
}
fun rand(start: Int, end: Int): Int {
//require(start <= end) { "Illegal Argument" }
return (start..end).random()
}
}

上面是我一直在写的代码。这是我的第一个项目,所以我不知道出了什么问题。我修复了numberGuess函数中的一个变量类型问题,但当我修复完它时,应用程序无法打开,虚拟设备显示";应用程序不断停止";错误

这是列出错误的运行日志。生成日志没有任何错误。

07/09 19:58:05: Launching 'app' on phone1.
Install successfully finished in 1 s 266 ms.
$ adb shell am start -n "com.example.absolutelydumb/com.example.absolutelydumb.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 5935 on device 'phone1 [emulator-5554]'.
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.absolutelydumb, PID: 5935
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.absolutelydumb/com.example.absolutelydumb.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:2843)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
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:159)
at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:157)
at android.content.Context.obtainStyledAttributes(Context.java:675)
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:692)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:659)
at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:479)
at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:214)
at com.example.absolutelydumb.MainActivity.<init>(MainActivity.kt:13)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1215)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2831)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:193) 
at android.app.ActivityThread.main(ActivityThread.java:6669) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 

在调用onCreate()setContentView()之前,不能调用findViewById。由于您在四个属性的声明站点上使用findViewById,因此在实例化Activity类时,也就是在调用onCreate之前,会调用它。

有两种方法可以解决这个问题。

  1. 使用lateinit var并在调用setContentView()后立即设置属性:
private lateinit var startButton: Button
//...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button = findViewById(R.id.startButton)
//...
  1. 使用by lazy,因此仅在首次访问属性时调用它,即在调用setContentView()之后:
private val startButton: Button by lazy { findViewById(R.id.startButton) }

或者,您可以使用视图绑定,它消除了大部分样板文件,并且不太容易出错。所谓易出错,我的意思是,您可以调用findViewById,意外地搜索当前布局中不存在的视图,它将在运行时崩溃。视图绑定使这不可能实现。

相关内容

最新更新