Intent는 컴포넌트(액티비티, 서비스, 브로드캐스트 리시버)간에 통신을 하기 위한 '메시지 객체'입니다.
Intent를 대표적 3가지 방법:
- 액티비티의 시작: startActivity(Intent), startActivityForResult(Intent, requestCode)
- 서비스의 시작: startService(Intent), bindService(Intent)
- 브로드케스트 전달: sendBroadcast(Intent), sendOrderedBroadcast(Intent), sendStickyBroadcast()
2가지 Intent 타입 : Explicit Intents (명시적), Implicit Intents (암시적).
1. Explicit Intents (명시적):
명시적 인텐트는 인텐트에 클래스 객체나 컴포넌트 이름을 지정하여 호출할 대상을 확실히 알 수 있는 경우에 사용한다. 시작할 컴포넌트 이름을 지정합니다
예를 들면 Activity들 간의 정보 전달시 명시적 Intent사용
Intent intent = new Intent(InputActivity.this, ResultActivity.class);
intent.putExtra("my_data", data);
startActivity(intent);
2. Implicit Intents (암시적):
특정 구성 요소의 이름을 대지 않지만, 그 대신 수행할 일반적인 작업을 선언하여 다른 앱의 구성 요소가 이를 처리할 수 있도록 해줍니다. 예를 들어 사용자에게 지도에 있는 한 위치를 표시하고자 하는 경우, 암시적 인텐트를 사용하여 해당 기능을 갖춘 다른 앱이 지정된 위치를 지도에 표시하도록 요청할 수 있습니다.
// 전화 거는 Intent
Intent intent = new Intent(Intent.ACTION_DIAL)
// google page 트는 Intent
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com/"));
(명시적) 이름지정 VS (암시적) 행동지정 쯤으로 생각해도 될까나??
IntentFilter
인텐트 필터는 컴포넌트가 수신하려는 인텐트 유형을 지정하는 매니페스트 파일의 표현식이다.
안드로이드 시스템 내부에선 수많은 앱들에 의해 수많은 인텐트들이 발생한다. 이 중 자신에게 필요한 인텐트만을 받기 위해 인텐트 필터가 있는 것이다.
- 인텐트 필터는 암시적 인텐트 실행을 위해 필요한 요소다.
- 사용할 인텐트가 여러 종류면 그 개수만큼 인텐트 필터를 매니페스트에 만들어야 한다.
PendingIntent
Intent를 가지고 있는 클래스로, 기본 목적은 다른 애플리케이션(다른 프로세스)의 권한을 허가하여 가지고 있는 Intent를 마치 본인 앱의 프로세스에서 실행하는 것처럼 사용하는 것이다.
다른 앱을 사용중에 Intent를 사용한 Notification을 클릭했을때 동작을 안함. 그래서 PendingIntent를 통해 다른 프로세스 (앱) 에게 권한을 허가하여 Intent 를 마치 본인 앱에서 실행되는 것처럼 사용하게 하는 것이다. 때문에 특정 시점에 Intent 가 무조건 수행될 수 있도록 보장되는 것이다.
사용 예:
- Notification (푸시알림) 으로 Intent 작업 수행시 사용
- 바탕화면 (런쳐) 위젯에서 Intent 작업 수행 시 사용
- AlarmManager 를 통해 지정된 시간에 Intent 작업 수행시 사용
Bundle
Bundle은 Map의 형태로 된 데이터 묶음이다. Map 형태라 key - String, value - int, String, boolean 같은 기본 타입부터 Serializable, Parcelable 같은 타입도 올수 있음
Serializable(객체 직렬화)는 객체를 바이트로 저장하는 자바의 인터페이스이고,
Parcelable는 안드로이드에서 만든 것이다.
클래스를 직렬화 하려면, 클래스에 implements Serializable 또는 implements Parcelable을 하여야 한다.
그런데 Android에서는 Activity간에 데이터를 주고 받을 때 Bundle 클래스를 사용하여 데이터를 전송한다.
출처: https://www.crocus.co.kr/1560 [Crocus:티스토리]
Bundle의 사용
1. Activity의 상태 저장 및 복구 (onSavedInstanceState, onRestoreInstanceState)
- Bundle은 데이터 저장 객체로써 상태 저장 및 복구에 사용된다. Activity가 onStop()이 되기 전에 onSavedInstanceState에서 저장할 데이터를 저장시키고, onStart() 이후에 onRestoreInstanceState에서 복구시킨다.
2. Intent의 extras를 이용하여 다른 구성요소 (Activity, Broadcast Reciever 등)에 데이터 전달
- Intent에서는 putExtra메서드를 이용해 데이터를 입력할수 있다. 이떄 입력되는 Extra가 바로 Bundle 객체이다.
- Intent putExtra 함수 내부적으로는 Bundle을 사용함.
onSavedInstanceState
휴대폰이 가로모드와 세로모드로 전환될때 onCreate 함수가 다시 호출된다. 또는 안드로이드 액티비티는 스마트폰 메모리가 부족해서 혹은 여러가지 이유로 종료 될수 있다. 이런 상황에서 데이터를 유지해야하는 경우가 있을때 onSavedInstanceState를 사용한다
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
if (savedInstanceState == null) {
Log.i(TAG, no Hi);
} else {
Log.i(TAG, "환생했음");
String hi = savedInstanceState.getString("인사");
Log.i(TAG, hi);
}
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("인사", "안녕하세요");
}
}
onRestoreInstanceState()
onStart() 다음에 호출됨. 그래서 onStart() 다음에 필요한 모든 초기화가 완료된후 안전하게 복구 가능.
Intent와 Bundle의 차이
Intent는 저장이 아닌 전달하는 수단으로의 객체이고 Bundle은 상태/값 등을 저장하기 위한 객체입니다.
객체 전달 방법 :
객체를 프로세스 간 전달하기 위해서는 직렬화 과정을 거쳐야 하기 때문에 Serializable이나 Parcelable을 구현한 클래스를 통해 보내주어야 합니다.
Serializable, Parcelable ???
직렬화란?
- 직렬화는 메모리 내에 존재하는 정보를 쉽게 전송 및 전달하기 위해 byte 코드 형태로 나열하는 것이다. 여기서 메모리 내에 존재하는 정보는 즉 객체를 말한다.
- JVM(Java Virtual Machine)의 메모리에 상주 되어있는 객체 데이터를 바이트 형태로 변환하는 기술
객체를 쉽게 전송하기 위해 byte 코드로 전송하는거. 안드로이드 앱을 개발한때는 액티비티간의 데이터를 전달할 때 인텐트를 사용하고 이 인텐트에 전달할 데이터를 추가합니다. 복잡한 클래스의 객체를 이동하려는 경우에는 Serializable 또는 Parcelabe을 사용하여 인텐트에 추가해서 데이터를 이동하면 된다.
역직렬화란?
- byte로 변환된 Data를 원래대로 Object나 Data로 변환하는 기술을 역직렬화라고 한다.
Serializable
- Serializable은 Android SDK가 아닌 표준 Java의 인터페이스이다.
- Serializable은 해당 클래스가 직렬화 대상이라고 알려주기만 할뿐 어떠한 메소드도 가지지 않는 단순한 마커 인터페이스이므로 사용자는 매우 쉽게 사용할 수 있다.
- Serializable 은 내부에서 Reflection 을 사용하여 직렬화를 처리
Parcelable
- Parcelable은 직렬화를 위한 또 다른 인터페이스이다. Serializable과는 달리 표준 Java가 아닌 Android SDK의 인터페이스이다.
- 사용자가 명시적으로 작성하기 때문에 Parcelabledms Reflection을 사용 안함.
Parcelable VS Serializable
시간 : Parcelable이 빠름
코드 추가 난이도 : Serializable이 쉬움
Parcelable은 Serializable보다 빠르지만 Serializable에서는 구현할필요 없는 필수 메서드들을 구현해야한다.
시간 VS 코드 추가 번거로움의 대결 같다.
'안드로이드 자바 코틀린 기초 지식 > 안드로이드 기초 지식' 카테고리의 다른 글
Context (0) | 2023.02.27 |
---|---|
Handler와 Looper (0) | 2023.02.27 |
바뀐 Fragment 생명주기 (0) | 2023.02.27 |
Activity LifeCycle ( 생명주기) (0) | 2023.02.27 |
ANR (Application Not Responding) (0) | 2023.02.27 |