[안드로이드] java.lang.nullpointerexception: attempt to invoke virtual method 'void android.widget.imageview.setimageresource(int)' on a null object reference
-
새로운 오류가 떴다.
기존에 주요 코드들만 가져와보았다.
server3.getPetRegister(textuser).enqueue(object :retrofit2.Callback<petListResponseDTO>{
@RequiresApi(Build.VERSION_CODES.O)
override fun onResponse(call: Call<petListResponseDTO?>?, response: Response<petListResponseDTO?>){
Log.d("반려동물 리스트", "" + response.body().toString())
Log.d("개수", response.body()?.result?.size!!.toString())
// 서버에서 가져온 데이터의 개수만큼 반복문을 실행합니다
for (i in 0 until (response.body()?.result?.size!!)) {
val namepet = response.body()?.result?.get(i)?.petName
val genderpet = response.body()?.result?.get(i)?.petGender
val birthpet = response.body()?.result?.get(i)?.petBirth
val agepet = response.body()?.result?.get(i)?.petAge
val speciespet = response.body()?.result?.get(i)?.petSpecies
val choiceLayout = createLayout(namepet!!,speciespet!!, birthpet!!, agepet!!)
petLayout.addView(choiceLayout)
}
}
override fun onFailure(call: Call<petListResponseDTO>, t: Throwable) {
Log.d("에러", t.message!!)
}
})
fun createLayout(name: String, species: String, birth: String, age: Int): View {
val inflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val layout = inflater.inflate(R.layout.activity_sub_pet, null) as LinearLayout
val petImg = findViewById<ImageView>(R.id.choicePetImg)
val petName = findViewById<TextView>(R.id.choicePetName)
val petAge = findViewById<TextView>(R.id.choicePetAge)
val petBirth = findViewById<TextView>(R.id.choicePetBirth)
petImg?.setImageResource(R.drawable.ex2)
petName?.text = name
petAge?.text = "나이: $age 살"
petBirth?.text = "생일: $birth"
choicePet?.setBackgroundColor(ContextCompat.getColor(this, R.color.white))
choicePet?.setImageResource(R.drawable.petchoice)
choicePet?.setPadding(0, 0, 0, 0)
layout.setOnClickListener {
val intent = Intent(applicationContext, VectorCamera::class.java)
intent.putExtra("namepet", name)
intent.putExtra("speciespet", species)
startActivity(intent)
}
return layout
}
서버에서 응답 결과를 받아 레이아웃 개수를 동적으로 추가해주고 각각의 레이아웃에 이미지, 서버에서 받아온 데이터들을 입력해주는 코드이다.
하지만, java.lang.nullpointerexception: attempt to invoke virtual method 'void android.widget.imageview.setimageresource(int)' on a null object reference 이런 오류가 떴다.
이 오류는 Null 참조로 인해 발생하는 예외이다.
해당 오류 메시지인 attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int)' on a null object reference는 ImageView.setImageResource() 메서드를 null인 객체에 대해 호출하려고 시도했기 때문에 발생한 오류이다.
해결 방법
처음엔 createLayout 함수에서 데이터 값이 잘 안받아와지는 줄 알았다.
로그를 찍어보니 데이터 값들은 잘 넘겨받아와졌다.
문제는 findviewbyid였다.
createLayout() 함수에서 각 뷰를 참조할 때, findViewById()를 사용하여 뷰를 찾고 있는데,
해당 함수는 findViewById()를 액티비티 클래스에서 사용하고 있는 것이 아니기 때문에, layout 뷰 내부에서 해당 뷰들을 찾을 수 없다.
해결하기 위해서는 layout 뷰 내부에서 각 뷰를 찾을 때, layout 뷰를 기준으로 findViewById()를 사용해야 한다.
이렇게 수정하면 layout뷰를 기준으로findViewById()를 호출하여 각 뷰를 찾아동적으로 생성된 레이아웃에 서버 응답 값을 올바르게 나타낼 수 있다.
수정되는 부분
val petImg = layout.findViewById<ImageView>(R.id.choicePetImg)
val petName = layout.findViewById<TextView>(R.id.choicePetName)
val petAge = layout.findViewById<TextView>(R.id.choicePetAge)
val petBirth = layout.findViewById<TextView>(R.id.choicePetBirth)