Issue
I am working on a android application that is NewsApp. I had made 2 activity. First is MainActivity and Second is HomeActivity. There is a button on MainActivity that is Register. If user press the button the MainActivity will be finish and HomeActivity appears but in my case when the user click register button the HomeActivity is not appearing and emulator show "App has stopped".
Since I am new to this I am not able to spot where the problem is and don't know how I can resolve it.
Thanks in advance.
The Error I am getting is:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.project.newsapp, PID: 8723
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
at com.project.newsapp.HomeActivity.onResponse(HomeActivity.kt:108)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
I am also attaching my HomeActivity and MainActivity code so you can tell me where I am doing it wrong.
My HomeActivity Code:
package com.project.newsapp
import android.app.ProgressDialog
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import com.project.newsapp.contract.Request
import com.project.newsapp.contract.Response
import com.project.newsapp.network.IRequestContract
import com.project.newsapp.network.NetworkClient
import com.project.newsapp.utils.Constant
import com.project.newsapp.utils.DataProvider
import com.project.newsapp.utils.showToast
import kotlinx.android.synthetic.main.activity_home.*
import kotlinx.android.synthetic.main.activity_home.btnExit
import kotlinx.android.synthetic.main.activity_main.*
import retrofit2.Call
import retrofit2.Callback
class HomeActivity : AppCompatActivity(), Callback<Response>, View.OnClickListener {
lateinit var userId:String
lateinit var userName:String
private val retrofitClient = NetworkClient.getNetworkClient()
private val requestContract = retrofitClient.create(IRequestContract::class.java)
private lateinit var sharedPreferences: SharedPreferences
private lateinit var progressDialog: ProgressDialog
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
progressDialog = ProgressDialog(this)
progressDialog.setMessage("Please wait...")
progressDialog.setCancelable(true)
sharedPreferences = getSharedPreferences(Constant.PREF_NAME, Context.MODE_PRIVATE)
title = "NewsApp"
userId = intent.getStringExtra(Constant.KEY_USER_ID).toString()
userName = intent.getStringExtra(Constant.KEY_USER_NAME).toString()
txtUserName.text = "Welcome $userName"
btnAllNews.setOnClickListener (this)
btnMyNews.setOnClickListener (this)
btnSignOut.setOnClickListener (this)
btnExit.setOnClickListener (this)
}
override fun onStart() {
super.onStart()
progressDialog.show()
val request = Request(
action = Constant.GET_NEWS,
userId = userId
)
val callResponse = requestContract.makeApiCall(request)
callResponse.enqueue(this)
}
override fun onClick(v: View?) {
when(v?.id){
R.id.btnAllNews -> {
if(DataProvider.response.allNews.size>0){
Intent(this,ViewAllNewsActivity::class.java).apply {
startActivity(this)
}
}else{
showToast("Blogs are not available")
}
}
R.id.btnMyNews -> {
}
R.id.btnSignOut -> {
signOut()
}
}
}
private fun signOut(){
val editor = sharedPreferences.edit()
editor.clear().commit()
Intent(this,MainActivity::class.java).apply{
startActivity(this)
finish()
}
}
override fun onResponse(call: Call<Response>, response: retrofit2.Response<Response>) {
if(progressDialog.isShowing)
progressDialog.dismiss()
if(response.body()!=null){
val serverResponse = response.body()
if(serverResponse!!.status){
DataProvider.response = serverResponse
}else{
showToast(serverResponse.message)
edUserName.setText("")
}
}
else{
showToast("Server is not responding. Please try again later.")
}
}
override fun onFailure(call: Call<Response>, t: Throwable) {
if(progressDialog.isShowing)
progressDialog.dismiss()
showToast("Server is not responding. Please try again later.")
}}
My MainActivity Code:
package com.project.newsapp
import android.app.ProgressDialog
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.project.newsapp.contract.Request
import com.project.newsapp.contract.Response
import com.project.newsapp.network.IRequestContract
import com.project.newsapp.network.NetworkClient
import com.project.newsapp.utils.Constant
import com.project.newsapp.utils.showToast
import kotlinx.android.synthetic.main.activity_main.*
import retrofit2.Call
import retrofit2.Callback
class MainActivity : AppCompatActivity(), Callback<Response> {
private val retrofitClient = NetworkClient.getNetworkClient()
private val requestContract = retrofitClient.create(IRequestContract::class.java)
private lateinit var progressDialog:ProgressDialog
private lateinit var sharedPreferences:SharedPreferences
lateinit var userName:String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
progressDialog = ProgressDialog(this)
progressDialog.setMessage("Please wait...")
progressDialog.setCancelable(true)
sharedPreferences = getSharedPreferences(Constant.PREF_NAME, Context.MODE_PRIVATE)
checkIfUserAlreadyRegistered()
btnRegister.setOnClickListener {
userName = edUserName.text.toString().trim().uppercase()
if(userName.isNullOrEmpty()){
showToast("Please Enter your Name")
}else{
progressDialog.show()
val request = Request(
action = Constant.REGISTER_USER,
userName = userName
)
val callResponse = requestContract.makeApiCall(request)
callResponse.enqueue(this)
}
}
/*btnExit.setOnClickListener {
finish()
}*/
}
override fun onFailure(call: Call<Response>, t: Throwable) {
if(progressDialog.isShowing)
progressDialog.dismiss()
showToast("Server is not responding. Please try again later.")
edUserName.setText("")
}
override fun onResponse(call: Call<Response>, response: retrofit2.Response<Response>) {
if(progressDialog.isShowing)
progressDialog.dismiss()
if(response.body()!=null){
val serverResponse = response.body()
if(serverResponse!!.status){
saveUserToPref(serverResponse.userId,userName)
Intent(this, HomeActivity::class.java).apply {
putExtra(Constant.KEY_USER_ID, serverResponse.userId)
putExtra(Constant.KEY_USER_NAME, userName)
startActivity(this)
finish()
}
}else{
showToast(serverResponse.message)
edUserName.setText("")
}
}
else{
showToast("Server is not responding. Please try again later.")
edUserName.setText("")
}
}
private fun saveUserToPref(userId:String, userName:String){
val editor = sharedPreferences.edit()
editor.putString(Constant.KEY_USER_ID,userId)
editor.putString(Constant.KEY_USER_NAME,userName)
editor.commit()
}
private fun checkIfUserAlreadyRegistered(){
val userId = sharedPreferences.getString(Constant.KEY_USER_ID,"invalid user id")
val userName = sharedPreferences.getString(Constant.KEY_USER_NAME,"invalid user name")
if(!userId.contentEquals("invalid user id")
&& !userName.contentEquals("invalid user name")){
Intent(this, HomeActivity::class.java).apply {
putExtra(Constant.KEY_USER_ID, userId)
putExtra(Constant.KEY_USER_NAME, userName)
startActivity(this)
finish()
}
}
}}
Solution
Kotlin synthetic accessors are deprecated.
One of the reasons why they are deprecated is that they lead to the error that you are seeing. edUserName
appears to be null
, implying that R.layout.activity_home
does not actually have a widget whose ID maps to edUserName
.
The problem may come from:
import kotlinx.android.synthetic.main.activity_main.*
Most likely, that should not be in HomeActivity
, since you are not using activity_main
there.
Answered By - CommonsWare
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.