When I am on activity A(Here LoginActivity) and went to activity B(Here MainActivity) using Intent and also call finish() function after Intent function Example:
if (isloggedIn){
val intent=Intent(this@LoginActivity,MainActivity::class.java)
startActivity(intent)
finish()
}
And from Activity B(Here MainActivity) when I press back button what will happen will Activity A again will be called by onCreate() or since it is out of the stack it i will be directed to my Homescreen of mobile?
I am currently have the error which make me confused about this:
I have made two Activity (A and B) mentioned above and uses AutoLogin feature for it. It works fine when user login for the first time but when user stops the app and clear the ram and again reopen the app it successfully went to Activity B(MainActivity) without asking Login credential of the user, but when I press back then the app crashes why?
Code:
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()
}
}
Error:
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)
CodePudding user response:
Your Problem:
You have written code that only calls setContentView
if the user is not logged in. So when the user is logged in, there are no views to find.
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)
The Solution
Either always call setContentView
so the view are available regardless of if you're logged in or not:
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)
OR ... just do an early 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)
OR ... extract your view set up logic into a function that is part of the else block:
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
}