액티비티 클래스에서 일반 클래스를 참조
요약
✔ 다른 클래스에 있는 멤버변수와 멤버함수에 접근하기 위해 인스턴스를 생성하는 방법
✔ 다른 클래스 객체 인스턴스를 멤버 변수에 넣고 lazy init 했을 때, 같은 인스턴스가 참조되는지 확인
✔ 런타임 시 한 번 생성되는 companion object에 있는 인스턴스 생성 함수를 각각 호출했을 때, 같은 인스턴스가 참조되는지 확인
코드
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
private val mTest by lazy { test() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
}
fun onClick(view: View) {
when(view.id) {
R.id.button -> {
mTest.printHello() // 멤버 변수 재참조
test().printHello() // 새로운 인스턴스 생성 함수
}
}
}
companion object {
private const val TAG = "MainActivity"
}
}
Test.kt
class Test private constructor() {
private var count = 0
fun printHello() {
LogUtil.d(TAG, "Hello")
LogUtil.d(TAG, "count : $count")
count++
}
companion object {
private const val TAG = "Test"
fun test() = Test()
}
}
로그
정리
✔ 현재 클래스에서 다른 클래스의 멤버를 사용하기 위한 방법
▫ 런타임 이후 한 번만 생성되는 참조할 클래스의 companion object에 생성자를 리턴하는 스태틱 함수를 만든다.
▫ 어떤 클래스든 해당 함수를 참조할 경우, 같은 주소에 있는 함수를 사용한다.
▫ 같은 주소에 있는 함수를 사용하지만, 리턴되는 생성자는 호출이 될 때마다 새로운 인스턴스를 반환한다.
✔ 객체 인스턴스를 멤버 변수에 넣고 lazy init 한 후, 멤버 변수를 재참조하면 같은 인스턴스를 참조한다.
✔ 객체 인스턴스를 멤버 변수에 넣지 않고 새로 생성할 경우, 서로 다른 새로운 인스턴스가 생성된다.
일반 클래스에서 액티비티 클래스를 참조
요약
✔ 일반 클래스에서 액티비티 클래스의 멤버 변수에 접근하는 방법
✔ 일반 클래스에서 액티비티 클래스의 Context을 넘겨받는 방법
경우
액티비티 클래스에서 생성자만 넘겨 줄 경우
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
}
fun onClick(view: View) {
when(view.id) {
R.id.button -> {
test().mainToast()
}
}
}
fun printHi() {
LogUtil.d(TAG, "Hi")
}
companion object {
private const val TAG = "MainActivity"
fun mainActivity() = MainActivity()
}
}
Test.kt
class Test {
fun mainToast() {
val mainContext = mainActivity()
Toast.makeText(mainContext, "Test 클래스 생성", Toast.LENGTH_SHORT).show() // Error
mainContext.printHi()
}
companion object {
private const val TAG = "Test"
fun test() = Test()
}
}
▫ 일반 클래스를 참조하는 방법처럼 생성자만 리턴할 경우, main에 있는 printHi()는 동작하지만, MainActivity의 Context가 필요한 Toast에서 Context가 포함되어 있지 않으므로 앱이 죽게된다.
액티비티 클래스에서 Context를 넘겨줄 경우
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
}
fun onClick(view: View) {
when(view.id) {
R.id.button -> {
test().mainToast()
}
}
}
fun printHi() {
LogUtil.d(TAG, "Hi")
}
init {
mainContext = this
}
companion object {
private const val TAG = "MainActivity"
private lateinit var mainContext: Context
fun mainContext() = mainContext
}
}
Test.kt
class Test {
fun mainToast() {
Toast.makeText(mainContext(), "Test 클래스 생성", Toast.LENGTH_SHORT).show()
val mainContext = mainContext() as MainActivity
mainContext.printHi()
}
companion object {
private const val TAG = "Test"
fun test() = Test()
}
}
▫ Context만 넘겨 받았을 경우, Context가 필요한 곳에서는 Context를 그대로 사용하면 되지만, MainActivity의 멤버에 접근하기 위해서는 Context를 MainActivity로 캐스팅 해 줘야 한다.
액티비티 클래스에서 Context를 포함한 액티비티 클래스를 넘겨줄 경우
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
}
fun onClick(view: View) {
when(view.id) {
R.id.button -> {
test().mainToast()
}
}
}
fun printHi() {
LogUtil.d(TAG, "Hi")
}
init {
mainContext = this
}
companion object {
private const val TAG = "MainActivity"
private lateinit var mainContext: MainActivity
fun mainContext() = mainContext
}
}
Test.kt
class Test {
fun mainToast() {
val mainContext = mainContext()
Toast.makeText(mainContext, "Test 클래스 생성", Toast.LENGTH_SHORT).show()
mainContext.printHi()
}
companion object {
private const val TAG = "Test"
fun test() = Test()
}
}
▫ Context를 포함한 액티비티를 넘겨 받았을 경우, Context가 필요한 곳에 액티비티를 그대로 넣어도 되고, 단독으로 참조해도 액티비티 클래스의 멤버에 접근할 수 있다.
'Android > Code' 카테고리의 다른 글
[ Android ] [ Kotlin ] 프래그먼트 onClick (0) | 2021.11.16 |
---|---|
[ Project ] [ Android ] [ Kotlin ] 콜백 함수 (0) | 2021.11.16 |
[Project] [Android] [Kotlin] Log Window (0) | 2021.10.18 |
[Android] [Kotlin] Google Map (0) | 2021.09.24 |
[Android] [Kotlin] EditText 자동 포커싱 및 키보드 (0) | 2021.09.23 |