버튼을 눌러 주사위를 굴려 값을 얻는 예제를 실행하기 위해 다음과 같이 코드를 작성하였다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.roll_button)
rollButton.setOnClickListener{
rollDice()
}
diceImage = findViewById(R.id.dice_image)
}
private fun rollDice() {
val randomInt = Random().nextInt(6) + 1
val drawableResource = when (randomInt){
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
val diceImage: ImageView = findViewById(R.id.dice_image)
diceImage.setImageResource(drawableResource)
}
}
26번째 줄을 보면 함수가 실행 될 때마다 diceImage 변수를 생성하여 findViewById 함수를 이용하여 초기화를 하기 때문에 비효율적이다.
val diceImage: ImageView = findViewById(R.id.dice_image)
findViewById 함수는 Id의 트리를 모두 탐색하기 때문에 여러번 호출하는 것은 앱의 실행 시간에 영향을 끼칠 수 있다.
따라서 다음과 같이 코드를 수정하였다.
class MainActivity : AppCompatActivity() {
val diceImage: ImageView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.roll_button)
rollButton.setOnClickListener{
rollDice()
}
diceImage = findViewById(R.id.dice_image)
}
private fun rollDice() {
val randomInt = Random().nextInt(6) + 1
val drawableResource = when (randomInt){
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
val diceImage: ImageView = findViewById(R.id.dice_image)
diceImage.setImageResource(drawableResource)
}
}
3번째 줄에 변수로 diceImage를 생성, null로 초기화해준다.
val diceImage: ImageView? = null
그러나 이 코드 역시 변수를 사용하기 위해서 null 체크를 해줘야 하는 번거로움이 남는다.
이를 다음과 같이 lateinit을 사용하면 나중에 변수의 값을 초기화 해줄 수 있다.
lateinit val diceImage: ImageView
하지만 이 코드를 실행하려고 하면 'lateinit' modifier is allowed only on mutable properties 라는 에러가 발생하는데
이는 lateinit 은 immutable(불변) 타입인 val에 사용할 수 없기 때문이다.
따라서 val 변수을 mutable(가변) 타입인 var으로 바꿔주면된다.
lateinit var diceImage: ImageView
class MainActivity : AppCompatActivity() {
lateinit var diceImage: ImageView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.roll_button)
rollButton.setOnClickListener{
rollDice()
}
diceImage = findViewById(R.id.dice_image)
}
private fun rollDice() {
val randomInt = Random().nextInt(6) + 1
val drawableResource = when (randomInt){
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
diceImage.setImageResource(drawableResource)
}
}
val 변수의 초기화를 나중에 하고 싶다면 'by lazy'를 사용하면 되는데 val 변수이기 때문에 나중에 한번 초기화한 이후엔 바꿀 수 없다.
val diceImage: ImageView by lazy
결론
- findViewById 함수를 여러번 호출하는 것은 앱의 실행 시간에 영향을 끼칠 수 있다.
- lateinit val은 불가능 하며 lateinit var를 사용하거나 by lazy를 사용한다.
참고
'Programming > Solution' 카테고리의 다른 글
[MySQL] function 생성: Sequel Pro (0) | 2020.06.27 |
---|---|
[Error] JqGrid JsonReader: pager 데이터 출력 안됨(TIMESTAMP) (1) | 2020.06.19 |
[Error] UnicodeEncodeError: 'latin-1' codec can't encode characters: Python (0) | 2019.12.08 |
[Error] Flask 500 Internal Server Error: html (2) | 2019.12.07 |
[Error] flask 실행 실패: Errno 48 (0) | 2019.12.07 |