새소식

오류일지

[안드로이드] 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 referenceImageView.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)

 

 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.