Android Developers 공식 문서 읽어보기
- Activity <- Here!
- Service
- Broadcast receiver
- Content provider
액티비티는 사용자와 상호작용하는 진입점으로 UI가 있는 단일 화면을 나타낸다.
이메일 앱에는 새 이메일 목록을 표시하는 활동, 이메일을 작성하는 활동, 이메일 읽기를 위한 활동이 하나씩 있을 수 있다. 이 여러 개의 활동들이 함께 작동하여 이메일 앱에서 일관된 환경을 형성하지만, 각 활동은 서로 독립적이다.
이메일 앱에서 허용하면 얼마든지 가능하다.
만약 이메일 앱에서 사용자가 사진을 첨부할 수 있도록 하고 싶다면? 카메라 앱을 시작해야한다. 이때 이메일 앱은 카메라 앱이 이메일 앱에서 시작되어 사진을 찍는다던가, 사진을 첨부한다던가와 같은 행위를 할 수 있도록 허용할 수 있다.
여기까지는 서론이었다... 서론이 길었다^^..
자, 그럼 본격적으로 액티비티라는 것이 무엇인지 공식 문서를 계속 읽어나가보자.
Activity 클래스는 안드로이드 앱에서 중요한 구성요소이며, 액티비티가 시작되어 조합되는 방식은 플랫폼 애플리케이션 모델의 기본적인 부분이다.
다른 앱이 main() 메서드로 실행되는 프로그래밍 패러다임과 달리, 안드로이드 시스템은 수명 주기의 특정 단계에 상응하는 특정 콜백 메서드를 호출하여 Activity 인스턴스의 코드를 시작한다.
1, 2와 같은 경우를 상상해보면,
둘 다 똑같이 이메일 앱을 실행하지만 그 과정에 있어서 다른 앱이 먼저 실행될 수 있다는 점과 이메일 앱을 실행하여 다른 액티비티를 바로 실행하는 점을 이해할 수 있겠다.
하나의 앱(SNS)이 다른 앱(이메일)을 호출하는 경우, 호출하는 앱(SNS)은 하나의 전체 액티비티가 아니라 다른 앱의 액티비티(이메일 쓰기)를 호출한다.
Activity 클래스는 이러한 상황에 잘 대응할 수 있도록 설계되었다.
이 window는 화면에 꽉 차 있는 것처럼 보이지만, 실제로는 화면보다 작을 수 있고 다른 창 위에 떠 있는 상태일 수도 있다.
서론에서 언급한 이메일 사례를 다시 생각해보면 되는데, 대부분의 앱에는 여러 화면이 표함되어 있다.
이말인 즉슨, 앱은 여러 개의 액티비티로 구성된다는 것이다!
앱에서 액티비티를 사용하려면 앱의 매니페스트에 액티비티에 관한 정보를 등록하고, 그 수명 주기를 적절하게 관리해야 한다.
매니페스트에는 사용할 액티비티와 해당 액티비티의 특정 속성을 선언해두어야 한다.
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
안드로이드 스튜디오를 열면 manifest 파일이 있을 것이다. 이를 열고, <activity>
요소를 <application>
요소의 하위 요소로 추가하면 해당 액티비티가 선언이 된다고 볼 수 있겠다.
android:name
은 액티비티 클래스의 이름을 지정하는 속성으로,<activity>
요소의 유일한 필수 속성이다.
<activity>
의 다른 속성들은 여기에서 자세히 볼 수 있다.
인텐트 : 메시지 객체. 앱 구성요소에 작업을 요청하는 데에 사용된다.
인텐트 필터 : 인텐트를 이용한 명시적, 암시적 요청을 기반으로 액티비티를 시작할 수 있는 기능을 제공한다.
시스템 UI에서 사용자에게 다른 앱 켜서 ~한 작업을 실행해볼것이여? 라고 사용할 앱을 묻는 메시지가 표시된다면? 그럼 인텐트 필터가 작동 중인 상태인 것이다.
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
이 코드는 텍스트 데이터를 전송하고, 다른 액티비티에서 요청을 수신하는 액티비티를 구성하는 코드이다.
<action>
요소 안에 <intent-filter>
속성이 선언된 것을 볼 수 있다.<category>
요소가 DEFAULT로 선언되어 있는데, 이는 액티비티가 실행 요청을 수신할 수 있는 상태라는 것이다.<data>
요소에는 이 액티비티가 전송할 수 있는 데이터 유형을 지정해둔 것이다.위 코드에서 선언해둔 액티비티를 호출하려면 아래와 같이 코드를 짜면 된다.
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, textMessage)
}
startActivity(sendIntent)
인텐트를 다룰 때 요긴하게 쓰일 것 같은 패턴이니, 잘 숙지해두면 좋겠다.
<activity>
태그를 사용하면 특정 액티비티를 시작할 수 있는 앱을 제어할 수 있다.내가 만들고 잇는 앱에서 SocialApp이라는 가상의 앱을 사용하여 소셜 미디어의 게시물을 공유하는 상황을 상상해보자.
1) 먼저, 내 앱에서 권한을 정의해야 한다.
정의해야 하는 권한은 com.google.socialapp.permission.SHARE_POST
이라고 가정하자.
<manifest>
<activity android:name="...."
android:permission="com.google.socialapp.permission.SHARE_POST" />
</manifest>
이렇게 android:permission
속성에 해당 권한을 정의해준다. 이는 내 앱이 SocialApp의 저 기능을 사용할 권한을 가지고 있다는 것이다.
나는 권한이 있는데, SocialApp에 권한이 없다면? 말짱 꽝이다. 만약 내가 중국 여행에 가기 위해 비자를 받았다고 치자. 나는 여권에는 A라는 비자를 받았지만, 막상 중국에서 관리하는 비자 리스트에 A라는 비자가 없다면? 공항에서 노숙만 하다 한국으로 돌아와야 할 것이다.
이를 위해,
2) SocialApp에서는 타 앱에서 해당 권한을 사용할 수 있도록 매니페스트에 해당 권한을 선언해줘야 한다.
<manifest>
<uses-permission android:name="com.google.socialapp.permission.SHARE_POST" />
</manifest>
이렇게하면, SocialApp은 내 앱으로부터 저 권한을 가지고 있는지 확인하고 관련 기능을 수행할 수 있는지 판단한다.
공식 문서에서 정말 정말 쉽게 설명하려고 노력한 것 같다. 더 필요한 내용은 보안 가이드라인 문서에서 (나중에) 더 찾아보자.
액티비티 수명 주기 관리는 이전에 다른 글에서 심도있게 다룬 바 있다.
간단하게 살펴 보자면,
애플리케이션 또는 사용자 데이터를 저장하거나, 네트워크를 호출하거나, 데이터베이스 트랜잭션을 실행하는 데 onPause()를 사용해서는 안 된다.
[TIL-240326]