일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 메모리 접근 충돌
- swiftdocs
- RxCocoa
- Automatically manage signing
- UICoordinateSpace
- RIBs Tutorial
- ios
- 대머리깃허브
- App Signing
- RxSwift
- in-out
- Concurrent
- Github file size
- Apple Certificate
- windowScene
- rib
- 로버트마틴형
- 클린아키텍쳐
- conflicting access to memory
- coordinateSpace
- Git Large File Storage
- iOS 버전 점유율
- Large File Storage
- Ribs
- Dependency Rule
- memory safety
- Dispatch.main.sync
- 잡초가득블로그
- iOS Target
- SWIFT
- Today
- Total
빙수왕의 개발일지
Activity에서 Activity로 값 전달하기 본문
Q) MainActivity에서 DestinationAcitivity로 "value1"과 "value2"를 전달하자.
-> 결론은 맨밑에 있음,,
1. 그저그런 방법
- 코틀린 허접인 나는 자바에서 많이 쓰던 방식을 그대로 사용했는데 .. 더 발전할 방향이 많다. 이렇게는 쓰지말자.. 흑흑
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent: Intent = Intent(applicationContext, DestinationActivity::class.java)
// 다른 곳의 companion object의 값들 쓸 떄 임포트 하지말자.
// 이유는 가독성 때문에! 어디서 온 앤지 한눈에 알기 힘들다..
intent.putExtra(DestinationActivity.VALUE_ONE, "value1")
intent.putExtra(DestinationActivity.VALUE_TWO, "value2")
startActivity(intent)
// 더 자세히 공부할 것 ::에 대하여..
// ::는 그 클래스의 클래스..(?)라는데 찾아보자.
}
DestinationActivity.kt
class DestinationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_destination)
val value1 = intent.getStringExtra(VALUE_ONE)
val value2 = intent.getStringExtra(VALUE_TWO)
}
// 선언 위치는 주체가 되는 쪽. 값을 받아서 사용하는 쪽. 호출하는 쪽에서보단 받는쪽이 좋다!
companion object {
const val VALUE_ONE = "value1"
const val VALUE_TWO = "value2"
}
}
2. 세련된 방법
* Kotlin의 스코프 함수를 사용했다. apply와 run
- 뭔가 코틀린스러워졌고 멋있어보인다. 왠지모르게 가독성이 좋다고 해야할 것 같다.
- apply는 주로 초기화 목적으로 사용되는 스코프 함수이고, 반환값이 수신 객체 자신이다.
- run은 이미 생성된 객체에 뭔가 작업이 필요할 때 사용하고, 반환값이 실행의 결과다. (받은 객체가 아님!)
* bundleOf를 사용하여 내용을 보냈다.
- bundleOf의 파라미터는 가변인자로 된 Pair형태다. 그래서 Pair 친구들을 보내야 하는데 여기서는 Pair(key, value) 이렇게 쓰기보다 "key to value" 와 같이 쓰는 방법을 사용했다. 이건 확실히 가독성이 더 좋은 것 같다.
- bundleOf의 장점은 Parcelable을 기본으로 사용하는 것이라고 한다. (Serializable보다 Parcelable이 성능이 좋음. 왜?)
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Intent(applicationContext, DestinationActivity::class.java).apply {
putExtras(bundleOf(
DestinationActivity.VALUE_ONE to "value1",
DestinationActivity.VALUE_TWO to "value2"
))
}.run {
startActivity(this)
}
}
DestinationActivity.kt
class DestinationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_destination)
val value1 = intent.extras?.get(VALUE_ONE)
val value2 = intent.extras?.get(VALUE_TWO)
}
// 선언 위치는 주체가 되는 쪽. 값을 받아서 사용하는 쪽. 호출하는 쪽에서보단 받는쪽이 좋다!
companion object {
const val VALUE_ONE = "value1"
const val VALUE_TWO = "value2"
}
}
3. 더 나은 방법
* Extension을 추가했다.
- startActivity라는 확장함수를 추가해서 액티비티에 value를 실어보내는 일련의 코드들을 완전 많이 줄였다. 한 번 선언해놓으면 훌륭하게 쓰일 것 같다.
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
startActivity<DestinationActivity>(
DestinationActivity.VALUE_ONE to "value1",
DestinationActivity.VALUE_TWO to "value2"
)
}
MyExtensions.kt
- extension이라는 패키지를 따로 만들고 그 안에 "MyExtensions.kt" 파일을 만들어서 추가해주었다.
- Anko라는 라이브러리에서 같은 기능을 제공했는데 이제는 deprecated 되었다고 한다. 참고하여 extension에 추가하면 된다고 함.
package com.example.lesson1.extension
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
inline fun <reified T: AppCompatActivity> Context.startActivity (
vararg extras: Pair<String, Any?>, // vararg는 가변인자. 원하는 갯수대로 넣기 가능 ~
intentAction: Intent.() -> Unit = {} // 고차함수 사용.
// 이 파라미터를 받으므로 인해서 함수(){"후처리내용"} 이런식으로 사용 가능하다.
// 스위프트의 후행클로저처럼..!
) {
startActivity(Intent(this, T::class.java).apply {
putExtras(bundleOf(*extras))
intentAction()
})
}
// 더 추가할 내용: 여기에 쓰인 inline, refied, 제너럴, <>, * 은 무엇인가?
DestinationActivity.kt
- 똑같쥬
class DestinationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_destination)
val value1 = intent.extras?.get(VALUE_ONE)
val value2 = intent.extras?.get(VALUE_TWO)
}
// 선언 위치는 주체가 되는 쪽. 값을 받아서 사용하는 쪽. 호출하는 쪽에서보단 받는쪽이 좋다!
companion object {
const val VALUE_ONE = "value1"
const val VALUE_TWO = "value2"
}
}
4. 오지는 방법
- 오지는건 내 개인적인 판단기준이다. 1이 내 코드였으므로 비교하면 거의 원시인에서 현대인으로 진화하엿음.
* startActivity 함수를 DestinationActivity의 companion object에 만들었다.
- 이렇게 하면 좋은점이. startActivity()할 때 에러가 안나니까 추가한 내용들을 놓칠 수 있는데, 이런식으로 하게되면 빌드 시 에러가 나서 조금 더 안전한 코드를 짤 수 있다!!
MainActivity.kt
- 한줄밖에 안된다!! 대박
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
DestinationActivity.startActivity(applicationContext, "value1", "value2")
}
MyExtensions.kt
- 3과 same same
package com.example.lesson1.extension
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
inline fun <reified T: AppCompatActivity> Context.startActivity (
vararg extras: Pair<String, Any?>, // vararg는 가변인자. 원하는 갯수대로 넣기 가능 ~
intentAction: Intent.() -> Unit = {} // 고차함수 사용.
// 이 파라미터를 받으므로 인해서 함수(){"후처리내용"} 이런식으로 사용 가능하다.
// 스위프트의 후행클로저처럼..!
) {
startActivity(Intent(this, T::class.java).apply {
putExtras(bundleOf(*extras))
intentAction()
})
}
// 더 추가할 내용: 여기에 쓰인 inline, refied, 제너럴, <>, * 은 무엇인가?
DestinationActivity.kt
- companion object에 함수를 만들어주었다.
class DestinationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_destination)
val value1 = intent.extras?.get(VALUE_ONE)
val value2 = intent.extras?.get(VALUE_TWO)
}
// 선언 위치는 주체가 되는 쪽. 값을 받아서 사용하는 쪽. 호출하는 쪽에서보단 받는쪽이 좋다!
companion object {
const val VALUE_ONE = "value1"
const val VALUE_TWO = "value2"
// 여기에 start 함수를 만들어줌. 어디서 이 액티비티를 호출하든 전달인자 필수요건으로 붙이기 가능.
// 이 안에 내용 적어서 MainActivity에서 DestinationActivity.start(this, "value1", "value2") 이렇게 호출한다.
// 이렇게 하면 좋은점이. startActivity()할 때 에러가 안나니까 추가한 내용들을 놓칠 수 있는데, 이런식으로 하게되면 빌드 시 에러가 나서 조금 더 안전한 코드를 짤 수 있다!!
fun startActivity(context: Context, value1: String, value2: String){
context.startActivity<DestinationActivity>(
VALUE_ONE to value1,
VALUE_TWO to value2
)
}
}
}
'개발 > Android' 카테고리의 다른 글
requireActivity()와 getActivity() (0) | 2020.08.06 |
---|---|
Fragment 생성 시 주의할 점 (0) | 2020.08.06 |
Activity에서 Fragment로 값 전달하기 (0) | 2020.08.06 |
클래스 레이아웃, 클래스 내용의 순서 (0) | 2020.08.06 |