개발/트러블 슈팅

03/21 주특기 1주차 트러블 슈팅

sos000303 2024. 3. 21. 19:33
728x90

Lv3 이후에 추가했던 기능인 액티비티를 호출할 때 5장의 이미지 파일 중에 랜덤한 이미지를 보여주는 기능을 만들 때 발생한 문제에 대해서 서술한다.

1. 문제의 발생

import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class HomeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home)

        val mainIV = findViewById<ImageView>(R.id.iv_logo)
        val idValueTV = findViewById<TextView>(R.id.tv_id_value_home)
        val finishBtn = findViewById<Button>(R.id.btn_finish)
        var randomNum = (1..5).random()
        var imageResource = resources.getIdentifier("img_${randomNum}", "drawable", packageName)

        idValueTV.text = intent.getStringExtra("EXTRA_ID")
        idValueTV.text = intent.getStringExtra("extra_id")
        mainIV.setImageResource(imageResource)

        mainIV.setOnClickListener{
            randomNum = (1..5).random()
            imageResource = resources.getIdentifier("img_${randomNum}", "drawable", packageName)
            mainIV.setImageResource(imageResource)
        }

        finishBtn.setOnClickListener {
            finish()
        }
    }
}

랜덤 이미지를 출력할때 받아오는 인수를 onCreat내부에 선언했다. 하지만 화면 회전을 할 때마다 이미지가 바뀌는 현상이 생겼다.

2. 사실확인 및 원인 분석

화면이 회전될 때 마다 onCreat되어 randomNum의 값이 바뀌어 이미지가 바뀌는 것이라 예상했다.

https://developer.android.com/guide/topics/resources/runtime-changes?hl=ko

공식문서를 찾아보니 기본적으로 시스템은 화면 구성이 변경(ex 화면 회전)이 발생하면 Activity를 onDestroy하고 다시 onCreate하여 구성을 초기화한다고 한다.

API 24(Android 7.0)이상에서는 화면 구성 변경이 클 경우에만 액티비티를 재생성하고 이외의 경우에는 onConfigurationChanged()라는 메서드를 호출해 사용한다고 한다.(Activity와 View의 메서드) 내가 개발하는 환경이 API30인데 30~33버전에서는 Activity.onConfigurationChanged() 가 호출되지 않아서 화면이 회전할 때마다 Activity가 재생성되어 이미지가 바뀌는 것으로 분석됐다.

3. 시도 및 결과

class SignInActivity : AppCompatActivity() {

    lateinit var startForResult: ActivityResultLauncher<Intent>
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sign_in)

        val loginBtn = findViewById<Button>(R.id.btn_login)
        val joinBtn = findViewById<Button>(R.id.btn_join)
        val idET = findViewById<EditText>(R.id.et_id)
        val passwordET = findViewById<EditText>(R.id.et_password)

        startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result ->
            if(result.resultCode == RESULT_OK){
                val id = result.data?.getStringExtra("signed_id")
                val password = result.data?.getStringExtra("signed_password")
                idET.setText(id)
                passwordET.setText(password)
            }
        }

        loginBtn.setOnClickListener {
            if(idET.text.isEmpty() || passwordET.text.isEmpty()){
                toastFun(this,"아이디/비밀번호를 확인해주세요.")
            }else {
                val intent = Intent(this, HomeActivity::class.java)
                intent.apply{
                    putExtra("extra_id", idET.text.toString())
                    putExtra("random", getRandomIndex())
                }
                toastFun(this, "로그인 성공")
                startActivity(intent)
            }
        }
        joinBtn.setOnClickListener {
            val intent = Intent(this, SignUpActivity::class.java)
            startForResult.launch(intent)

간단하게 HomeActivity가 아닌 이전단계의 SignInActivity에서 랜덤값을 Extra로 넘겨서 해결했다. 넘어온 값은 변하지 않고 intent가 넘어갈 때 랜덤값이 부여되므로 원했던 결과를 얻었다.

728x90