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가 넘어갈 때 랜덤값이 부여되므로 원했던 결과를 얻었다.
'개발 > 트러블 슈팅' 카테고리의 다른 글
| 04/16 수준별 4주차 과제 트러블 슈팅 (0) | 2024.04.16 |
|---|---|
| 03/14 간단한 키오스크 만들기 (1) | 2024.03.14 |
| 03/05 Toolbar 이동 기능 트러블 슈팅 (0) | 2024.03.05 |