버튼을 눌러 주사위를 굴려 값을 얻는 예제를 실행하기 위해 다음과 같이 코드를 작성하였다.
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를 사용한다.
참고
Developing Android Apps with Kotlin
Learn the fundamentals of the Kotlin programming language from Kotlin experts at Google.
www.udacity.com
'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 |