当我按下后退按钮时 activity 会发生什么?
What happen to the activity when i press back button?
当我在 activity A(Here LoginActivity) 并使用 Intent 转到 activity B(Here MainActivity) 并调用 finish()功能
在 Intent 函数之后
示例:
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
}
从 Activity B(这里是 MainActivity) 当我按下后退按钮时会发生什么 Activity A 将再次被 onCreate() 调用或者因为它已经退出在堆栈中,我将被定向到我的手机主屏幕?
我目前有错误让我对此感到困惑:
我制作了上面提到的两个 Activity(A 和 B),并为其使用了自动登录功能。当用户第一次登录时它工作正常但是当用户停止应用程序并清除 ram 并再次重新打开应用程序时它成功地转到 Activity B(MainActivity) 而无需询问用户的登录凭据,但是当我按回键时应用程序崩溃了,为什么?
代码:
class LoginActivity : AppCompatActivity(){
lateinit var phone_num:EditText
lateinit var password_num:EditText
lateinit var button_login:Button
lateinit var txtForgotPassword:TextView
lateinit var RegisterYouself:TextView
val ValidMobileNumber="0123"
val ValidPassword= arrayOf("Iron","captain","hulk","avenger")
lateinit var SharedPreferences:SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
SharedPreferences=getSharedPreferences(getString(R.string.Prefereces_file_name), Context.MODE_PRIVATE)
val isloggedIn=SharedPreferences.getBoolean("isLoggedIn",false)
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
}
else {
setContentView(R.layout.activity_login)
}
title="Log In"
phone_num=findViewById(R.id.phone_num)
password_num=findViewById(R.id.password_num)
button_login=findViewById(R.id.button_login)
txtForgotPassword=findViewById(R.id.txtForgotPassword)
RegisterYouself=findViewById(R.id.RegisterYouself)
button_login.setOnClickListener{
val mobilenumber=phone_num.text.toString()
val password=password_num.text.toString()
var nameOfAvenger="Avenger"
val intent=Intent(this@LoginActivity,MainActivity::class.java)
if (mobilenumber==ValidMobileNumber){
if (password==ValidPassword[0]){
nameOfAvenger="Iron Man"
savePreferences(nameOfAvenger)
startActivity(intent)
}
else if (password==ValidPassword[1]){
nameOfAvenger="Captain America"
savePreferences(nameOfAvenger)
startActivity(intent)
}
else if(password==ValidPassword[2]){
nameOfAvenger="Hulk"
savePreferences(nameOfAvenger)
startActivity(intent)
}
else if (password==ValidPassword[3]){
nameOfAvenger="The Avenger"
savePreferences(nameOfAvenger)
startActivity(intent)
}
else {
Toast.makeText(
this@LoginActivity, "Incorrect creditial", Toast.LENGTH_LONG
).show()
}
}
else {
Toast.makeText(
this@LoginActivity, "Incorrect creditial", Toast.LENGTH_LONG
).show()
}
}
}
fun savePreferences(title:String){
SharedPreferences.edit().putBoolean("isLoggedIn",true).apply()
SharedPreferences.edit().putString("Title",title).apply()
}
}
错误:
Process: com.mustafa.activitylifecycle, PID: 26158
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mustafa.activitylifecycle/com.mustafa.activitylifecycle.LoginActivity}: java.lang.NullPointerException: findViewById(R.id.phone_num) must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
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: findViewById(R.id.phone_num) must not be null
at com.mustafa.activitylifecycle.LoginActivity.onCreate(LoginActivity.kt:43)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
您的问题:
您编写的代码仅在用户未登录时调用 setContentView
。因此当用户 登录时,没有可查找的视图。
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish() // JUST BECAUSE YOU CALL FINISH DOES NOT MEAN THE METHOD STOPS EXECUTING
}
else {
// CONTENT ONLY BEING SET IF NOT LOGGED IN
setContentView(R.layout.activity_login)
}
title="Log In"
// IF NOT LOGGED IN, THERE IS NO "phone_num" TO FIND!!!! CRASH! BOOM!
phone_num=findViewById(R.id.phone_num)
password_num=findViewById(R.id.password_num)
解决方案
总是调用 setContentView
,这样无论您是否登录,视图都可用:
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
}
// REMOVE THE "else" - ALWAYS SET VIEWS SO THEY'RE VALID
setContentView(R.layout.activity_login)
title="Log In"
phone_num=findViewById(R.id.phone_num)
password_num=findViewById(R.id.password_num)
或者 ... 早点做 return:
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
return // EARLY RETURN TO PREVENT THE REST OF THE IRRELEVANT CODE FROM RUNNING
}
else {
setContentView(R.layout.activity_login)
}
title="Log In"
phone_num=findViewById(R.id.phone_num)
password_num=findViewById(R.id.password_num)
或者 ... 将您的视图设置逻辑提取到属于 else 块的函数中:
fun onCreate(...) {
if (isloggedIn) {
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
}
else {
initializeActivity()
}
}
fun initializeActivity() {
setContentView(R.layout.activity_login)
title="Log In"
phone_num=findViewById(R.id.phone_num)
password_num=findViewById(R.id.password_num)
// ETC
}
当我在 activity A(Here LoginActivity) 并使用 Intent 转到 activity B(Here MainActivity) 并调用 finish()功能 在 Intent 函数之后 示例:
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
}
从 Activity B(这里是 MainActivity) 当我按下后退按钮时会发生什么 Activity A 将再次被 onCreate() 调用或者因为它已经退出在堆栈中,我将被定向到我的手机主屏幕?
我目前有错误让我对此感到困惑:
我制作了上面提到的两个 Activity(A 和 B),并为其使用了自动登录功能。当用户第一次登录时它工作正常但是当用户停止应用程序并清除 ram 并再次重新打开应用程序时它成功地转到 Activity B(MainActivity) 而无需询问用户的登录凭据,但是当我按回键时应用程序崩溃了,为什么?
代码:
class LoginActivity : AppCompatActivity(){
lateinit var phone_num:EditText
lateinit var password_num:EditText
lateinit var button_login:Button
lateinit var txtForgotPassword:TextView
lateinit var RegisterYouself:TextView
val ValidMobileNumber="0123"
val ValidPassword= arrayOf("Iron","captain","hulk","avenger")
lateinit var SharedPreferences:SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
SharedPreferences=getSharedPreferences(getString(R.string.Prefereces_file_name), Context.MODE_PRIVATE)
val isloggedIn=SharedPreferences.getBoolean("isLoggedIn",false)
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
}
else {
setContentView(R.layout.activity_login)
}
title="Log In"
phone_num=findViewById(R.id.phone_num)
password_num=findViewById(R.id.password_num)
button_login=findViewById(R.id.button_login)
txtForgotPassword=findViewById(R.id.txtForgotPassword)
RegisterYouself=findViewById(R.id.RegisterYouself)
button_login.setOnClickListener{
val mobilenumber=phone_num.text.toString()
val password=password_num.text.toString()
var nameOfAvenger="Avenger"
val intent=Intent(this@LoginActivity,MainActivity::class.java)
if (mobilenumber==ValidMobileNumber){
if (password==ValidPassword[0]){
nameOfAvenger="Iron Man"
savePreferences(nameOfAvenger)
startActivity(intent)
}
else if (password==ValidPassword[1]){
nameOfAvenger="Captain America"
savePreferences(nameOfAvenger)
startActivity(intent)
}
else if(password==ValidPassword[2]){
nameOfAvenger="Hulk"
savePreferences(nameOfAvenger)
startActivity(intent)
}
else if (password==ValidPassword[3]){
nameOfAvenger="The Avenger"
savePreferences(nameOfAvenger)
startActivity(intent)
}
else {
Toast.makeText(
this@LoginActivity, "Incorrect creditial", Toast.LENGTH_LONG
).show()
}
}
else {
Toast.makeText(
this@LoginActivity, "Incorrect creditial", Toast.LENGTH_LONG
).show()
}
}
}
fun savePreferences(title:String){
SharedPreferences.edit().putBoolean("isLoggedIn",true).apply()
SharedPreferences.edit().putString("Title",title).apply()
}
}
错误:
Process: com.mustafa.activitylifecycle, PID: 26158
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mustafa.activitylifecycle/com.mustafa.activitylifecycle.LoginActivity}: java.lang.NullPointerException: findViewById(R.id.phone_num) must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
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: findViewById(R.id.phone_num) must not be null
at com.mustafa.activitylifecycle.LoginActivity.onCreate(LoginActivity.kt:43)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
您的问题:
您编写的代码仅在用户未登录时调用 setContentView
。因此当用户 登录时,没有可查找的视图。
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish() // JUST BECAUSE YOU CALL FINISH DOES NOT MEAN THE METHOD STOPS EXECUTING
}
else {
// CONTENT ONLY BEING SET IF NOT LOGGED IN
setContentView(R.layout.activity_login)
}
title="Log In"
// IF NOT LOGGED IN, THERE IS NO "phone_num" TO FIND!!!! CRASH! BOOM!
phone_num=findViewById(R.id.phone_num)
password_num=findViewById(R.id.password_num)
解决方案
总是调用 setContentView
,这样无论您是否登录,视图都可用:
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
}
// REMOVE THE "else" - ALWAYS SET VIEWS SO THEY'RE VALID
setContentView(R.layout.activity_login)
title="Log In"
phone_num=findViewById(R.id.phone_num)
password_num=findViewById(R.id.password_num)
或者 ... 早点做 return:
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
return // EARLY RETURN TO PREVENT THE REST OF THE IRRELEVANT CODE FROM RUNNING
}
else {
setContentView(R.layout.activity_login)
}
title="Log In"
phone_num=findViewById(R.id.phone_num)
password_num=findViewById(R.id.password_num)
或者 ... 将您的视图设置逻辑提取到属于 else 块的函数中:
fun onCreate(...) {
if (isloggedIn) {
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
}
else {
initializeActivity()
}
}
fun initializeActivity() {
setContentView(R.layout.activity_login)
title="Log In"
phone_num=findViewById(R.id.phone_num)
password_num=findViewById(R.id.password_num)
// ETC
}