Intent?
- 컴포넌트를 실행하기 위해 시템에 전달하는 메시지
- 즉, 데이터를 담는 클래스
- 컴포넌트는 개발자가 직접 생성하고 관리하고 파괴할 수 없다.
- 즉, 코드로 생명주기를 관리 할수 없다.
- 그래서 새로운 컴포넌트를 생성하기 위해 우리는 시스템에 정보를 전달하여 시스템에 생명주기를 맡기게 된다.
- 이때, 시스템에게 정보를 전달할 수 있는 매개체가 인텐트이다.
- 시스템은 인텐트의 정보를 분석해서 그에 맞는 컴포넌트를 실행해 준다.
- 앞서 startActivity()에서 인텐트를 담아 전달할 때
- Intent 생성자에 생성할 컴포넌트의 클래스 레퍼런스 정보를 담아 시스템에 해당 컴포넌트를 실행해 달라는 정보를 담아서 startActvity를 통해 전달하는 것이다.
Intent Extra Data
- 개발자가 새로운 컴포넌트에 데이터를 넘길 때 인텐트에 데이터를 담아서 시스템에 같이 전달한다.
- 이때, 개발자가 이 인텐트에 담는 데이터는 부가 정보이고 이를 엑스트라 데이터라 한다.
- putExtra를 통해서 데이터를 담고 전달한다.
- 파라미터 값은 key와 value이며, key는 string으로 전달한다.
- 이를 통해 받을 땐 getExtra를 통해 받는다. 또한 다양한 타입별로 데이터를 받을 수 있다.
- getIntExtra
- getStringExtra
- getDoubleExtra
- …
🎯 Intent filter
- intent는 실행할 컴포넌트 정보 설정 방법에 따라 2가지로 분류됨
- 명시적 인텐트
- 클래스 타입 레퍼런스 정보를 활용한 인텐트
- 암시적 인텐트
- 인텐트 필터 정보를 활용한 인텐트
명시적 인텐트
- 인텐트 필터 정보를 활용한 인텐트
- 명시적 인텐트
- 일반적으로 내부 앱의 컴포턴트를 요청하는 인텐트 객체를 만들 때 사용
암시적 인텐트
- 외부 앱의 컴포넌트의 경우 내부 클래스 명을 알 수 없음
- 따라서, 인텐트 필터 정보를 이용한 암시적 인텐트를 활용함
- 이는 manifest 설정 파일에 선언된 인텐트 필터를 이용함
intent filter tag
- action: 컴포넌트의 기능을 나타내는 문자열
- name
- 이는 유일할 필요는 없으나 컴포넌트의 기능을 나타낼 것을 권장함
- name
- category: 컴포넌트가 포함되는 범주를 나타내는 문자열
- name
- 여기에 범주를 기재함
- 개발자가 임의 지정을 할 수 있으나 플랫폼 API에서 제공하는 문자열 사용
- ex) android.intent.category.LAUNCHER
- name
- data: 컴포넌트에 필요한 데이터 정보
- 컴포넌트에서 어떤 성격의 데이터를 처리하는지 나타냄
- 여러 속성이 있으며 필요한만큼 이용가능
- intent 등록 예제
<activity android:name=".TwoActivity"> <intent-filter> <action android:name="ACTION_EDIT" /> <category android:name="android.intent.category.DEFAULT"/ > <data android:scheme="http" /> </intent-filter> </activity>
- intent 프로퍼티 이용 예제
val intent = Intent() intent.action = "ACTION_EDIT" intent.data = Uri.parse("http://www.google.com") startActivity(intent)
🎯 Intent를 통해 객체 전달
object를 직렬화 하여 intent로 전달한다.
- Serializable
- data class
data class Object: Serializable { ... }
- input intent
val intent = Intent() intent.putExtra("serial", object)
- get object
obj: Object = intent.getSerializableExtra("serial")
- data class
- Parcelable
- data class
data class object: Parcelable { ... override fun describeContents(): Int { return 0; } override fun writeToParcel(dest: Parcel,flags: Int) { } }
- input intent
val intent = Intent() intent.putExtra("parcel", object)
- get object
obj: Object = intent.getParcelableExtra("parcel")
직렬화는 JVM의 메모리에만 상주되어 있는 객체 데이터를 그대로 영속화(persist)가 필요할 때 사용된다.
즉, intent에 담아 시스템에 전달할 때까지 jvm의 메모리에 데이터를 존재하게 하고, 이를 그대로 다음 컴포넌트에 전달하는 것이 목적이다.
- data class
- 추가적인 아이디어
- data class의 경우 toString() 메소드를 통해 문자열로 변환 후 getStringExtra를 통해 데이터를 받는다.
- 받은 후 데이터 파싱을 통해 객체 변환을 수행한다.
- Gson을 활용
- 네트워크 통신할 때 사용하는 라이브러리
- 이는 java object의 직렬화와 역직렬화를 수행해주어 편하게 데이터를 전달할 수 있다.
- data class
data class Object{ ... }
- input intent
val intent = Intent() myJson: String = gson.toJson(object); intent.putExtra("myjson", myjson);
- get object
val object = gson.fromJson<Object>(intent.getStringExtra("identifier"), Object::class.java)
- data class의 경우 toString() 메소드를 통해 문자열로 변환 후 getStringExtra를 통해 데이터를 받는다.