안드로이드 개발자 로드맵 — Part2: App Components

Jaewoong Eum·2022년 6월 28일
15
post-thumbnail

원문은 The 2022 Android Developer Roadmap — Part2에서 확인하실 수 있습니다.

안드로이드 채팅 솔루션에 관심이 있으신 분들은 Stream의 Android Chat Messaging Tutorial 페이지를 방문해 주시길 바랍니다.

Android developer roadmap은 총 5부로 연재될 예정이며, 각 회차는 안드로이드 생태계의 다양한 측면을 다룹니다. 지난 포스트에서는 Android languages, Operating System, the Android Platform, App Manifest를 포함하여 전반적인 안드로이드 시스템 아키텍처에 대하여 다루었습니다.

2부에서는 Android 로드맵의 다음 세 섹션을 다룹니다.

  • App Components
  • Intents
  • App Entry Points

향후 게시물에 대한 알림을 받고 싶으시다면, GitHub의 watchers에서 알림 등록을 해주시거나 메인테이너를 팔로우해 주시길 바랍니다.

이제 시작해 보도록 하겠습니다!

App Components (앱 컴포넌트)

Android 개발에서 앱 컴포넌트는 안드로이드 시스템 및 사용자가 애플리케이션과 상호 작용할 수 있도록 하는 entry point(진입점)과 같습니다. 각 컴포넌트는 생성 및 소멸 방법을 결정하는 고유한 기능과 수명 주기가 있습니다.

각 구성 요소에 대해 살펴보도록 하겠습니다.

Activities (액티비티)

Activity는 UI 관련 리소스를 제공하여 사용자와 상호 작용하는 독립적이고 재사용 가능한 구성 요소입니다. 모든 Android 애플리케이션에는 사용자와 상호 작용하기 위한 Activity가 최소 하나 이상 존재해야 합니다.

Activity Lifecycles (액티비티 생명 주기)

모든 Activity는 고유한 생명 주기가 있으며, 이는 Activity 및 리소스를 관리하는 데 중요한 개념입니다. Activity 클래스는 수명 주기 상태가 변경되었음을 Activity에 알리는 주요한 메서드들을 제공합니다.

해당 메서드들은 아래 그림에 표시된 생명 주기 순서에 따라 호출됩니다.

생명 주기 콜백 메서드를 사용하여 Activity가 동작하는 방식을 정의하고, 리소스를 효율적으로 관리할 수 있습니다. 이 섹션에서는 여섯 가지 주요 메서드에 대해 설명합니다.

  • onCreate(): 이 콜백은 시스템이 Activity를 생성할 때 호출됩니다. Activity의 생명 주기에서 단 한 번만 발생해야 하는 대부분의 초기화 로직은 여기에서 처리되어야 합니다. (예: View 초기화 및 데이터 바인딩).

  • onStart(): 이 콜백은 onCreate() 메서드를 호출한 후, Activity가 사용자에게 보여질 때 호출됩니다. 여러 개의 Activity 또는 애플리케이션 간에 화면을 전환하는 경우 이 콜백 함수는 두 번 이상 호출될 수 있습니다.

  • onResume(): Activity가 foreground로 노출되어 사용자와 상호 작용할 준비가 되었음을 의미합니다.

  • onPause(): Activity가 더 이상 사용자에게 보여지고 있지 않지만, 여전히 부분적으로 보여질 수 있음을 의미합니다 (예: 사용자가 멀티 윈도우 모드에 있는 경우). 대부분의 경우는 사용자가 Activity를 떠나고 생명 주기가 다음 상태로 전환됨을 나타냅니다.

  • onStop(): 이 콜백은 Activity가 사용자에게 더 이상 보여지지 않을 때 호출됩니다. 여러 Activity 또는 애플리케이션 간에 전환하는 경우 이 콜백 함수는 두 번 이상 호출될 수 있습니다.

  • onDestroy(): 이 콜백은 Activity가 완전히 파괴되기 전에 호출됩니다. 시스템은 Activity가 종료되거나 화면전환으로 인해 시스템이 Activity를 일시적으로 파괴할 때 이 콜백을 호출합니다. 이 콜백은 남은 모든 리소스를 해제하고 Garbage Collector가 할당된 모든 메모리를 회수하도록 할 때 사용할 수 있습니다.

더 자세한 내용은 the activity lifecycle을 참고해 주세요.

Creating an Activity (액티비티 생성하기)

Activity를 생성하려면 Activity 클래스를 상속받는 클래스를 생성해야 합니다. 최신 안드로이드 개발에서는 Jetpack 라이브러리를 활용하여 AppCompatActivity, FragmentActivityComponentActivity와 같은 Activity 클래스를 사용하며 Themes (테마), Fragments (프래그먼트) 등과의 호환성도 함께 지원합니다.

다음 코드를 사용하여 기본적인 Activity를 생성할 수 있습니다.

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

앱에서 생성한 Activity를 사용하기 위해서는 반드시 아래와 같이 App Manifest에 정의해야합니다.

<manifest ... >
  <application ... >
      <activity android:name=".MainActivity" />
      ...
  </application ... >
  ...
</manifest >

더 자세한 내용은 Introduction to Activities를 참고해 주세요.

Services (서비스)

Service는 원격 프로세스에 대한 기능을 수행하고 백그라운드에서 음악 플레이어 또는 Youtube 비디오 플레이어와 같이 장기적으로 수행되는 작업을 실행하도록 설계된 entry point(진입점) 입니다.

Service Lifecycles (서비스 생명 주기)

Service에는 고유한 생명 주기가 있으며, Service 시작하고 관리하는 두 가지 유형을 제공합니다.

  • startService: 다른 컴포넌트들은 startService()를 호출하여 Service를 실행할 수 있습니다. 이 Service는 백그라운드에서 실행되며 다른 컴포넌트에서 stopService()를 호출하여 서비스를 중지할 수 있습니다.

  • bindService: 다른 컴포넌트나 클라이언트는 bindService()를 호출하여 Service를 실행할 수 있습니다. bindService() 함수는 클라이언트가 Service와 일관되게 통신할 수 있도록 하는 IBinder 인터페이스를 제공합니다. 이 Service는 백그라운드에서 실행됩니다. 다른 컴포넌트나 클라이언트도 unbindService를 호출하여 실행을 중단할 수 있습니다.

아래 그림에서 볼 수 있듯이 Service의 생명 주기는 생성 방법에 따라 다릅니다.

Android 공식 문서에 따르면 위의 그림은 startService()에 의해 생성된 Service와 bindService()에 의해 생성된 Service를 구분하지만, Service가 시작되는 방식에 관계없이 잠재적으로 클라이언트가 Service 바인딩하도록 허용할 수 있습니다.

Creating a Service (서비스 생성하기)

Service를 생성하려면 아래 예제와 같이 Service 클래스를 상속받는 클래스를 생성해야 합니다.

class MyService : Service() {

    private var binder: IBinder? = null

    override fun onCreate() {
        // The service is being created
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return super.onStartCommand(
            intent,
            flags,
            startId
        ) // indicates how to behave if the service is killed
    }

    override fun onBind(intent: Intent?): IBinder? {
        // A client is binding to the service with bindService()
        return binder
    }

    override fun onDestroy() {
        // The service is no longer used and is being destroyed
    }
}

다음으로 앱이 Service를 사용하도록 하려면 아래와 같이 App Manifest에 정의해야 합니다.

<manifest ... >
  <application ... >
      <service android:name=".MyService" />
      ...
  </application ... >
  ...
</manifest >

더 자세한 내용은 service overview를 확인해 주세요.

Broadcast Receiver (브로드캐스트 리시버)

Broadcast receiver는 안드로이드 시스템 및 기타 안드로이드 응용 프로그램에서 broadcast 메시지를 청취하도록 등록 가능한 수신기입니다. 안드로이드 문서에 따르면, broadcast는 시스템이 부팅되거나 기기가 충전을 시작할 때와 같이 일반적인 시스템 변화를 앱에서 메시지 형태로 관찰하는 데 사용됩니다.

Broadcast receiver는 Activity나 Service와 달리 수명 주기가 없습니다. 대신, 등록이 취소될 때까지 할당된 모든 이벤트 메시지를 수신합니다.

Creating a Broadcast Receiver (브로드캐스트 리시버 만들기)

Broadcast Receiver를 만들기 위해서는 아래와 같이 Broadcast Receiver를 상속받는 클래스를 생성해야 합니다.

class MyBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        // do something
    }
}

다음으로 앱에서 Broadcast Receiver를 사용하도록 하려면, 아래와 같이 App Manifest에 정의해아합니다.

<receiver android:name=".MyBroadcastReceiver"  android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
    </intent-filter>
</receiver>

Content Providers (콘텐츠 프로바이터)

Content Provider는 애플리케이션의 데이터에 액세스하고 다른 애플리케이션과 공유하는 기능을 제공합니다. Android 문서에 따르면 Content Provider는 파일 시스템, SQLite 데이터베이스, Jetpack Room 또는 웹에 저장된 모든 종류의 영구 데이터를 여러 앱 간에 공유할 수 있도록 합니다.

Content Provider는 자체적인 보안 시스템이 적용되어 있으며, 사용자 권한을 요구하여 내부적으로 데이터를 보호합니다. 요청하는 애플리케이션에 필요한 권한이 없으면 Content Provider의 데이터에 접근할 수 없습니다.

더 자세한 내용은 creating a content provider를 참고해 주세요.

Intents (인텐트)

인텐트는 나중에 실행할 작업에 대한 추상적인 정의입니다. 예를 들어 앱 컴포넌트의 진입점을 실행하거나 Broadcast Receiver에 메시지를 보낼 수 있습니다.

Use Cases of Intents (인텐트 사용 사례)

Android 문서에 따르면 다음은 인텐트의 가장 일반적인 사용 사례입니다.

  • Activity 실행: 인텐트를 startActivity() 메서드에 실행하여 새 Activity를 실행할 수 있습니다. 인텐트는 Activity의 수행 동작을 정의하고 새 Activity에서 사용해야 하는 데이터를 전달합니다.

  • Service 실행: 인텐트를 startService() 메서드에 전달하여 새 Service를 실행할 수 있습니다. 인텐트는 Service의 동작을 정의하고 새로운 Service에서 사용해야 하는 데이터를 전달합니다.

  • Broadcast Receiver에 메시지 전달: sendBroadcast() 또는 sendOrderedBroadcast() 메서드에 인텐트를 전달하여 Broadcast Receiver에 메시지를 전달할 수 있습니다. 다른 컴포넌트 또는 다른 앱에서 broadcast 메시지로 인텐트를 전달할 수 있습니다.

Intent Types (인텐트 타입)

  • Explicit Intents (명시적 인텐트): 명시적 인텐트에는 애플리케이션의 패키지 이름 또는 컴포넌트의 클래스 이름과 같이 명시적인 정보가 포함됩니다. 예를 들어, Activity/Service를 실행하거나 명시적 대상 클래스 또는 패키지 정보를 포함하는 인텐트를 사용하여 Broadcast Receiver에 메시지를 보낼 수 있습니다.

  • Implicit Intents (암시적 인텐트): 암시적 인텐트는 지정된 대상 정보를 포함하지 않고 해당 동작을 대신 수행할 일반 작업을 선언합니다. 예를 들어 갤러리에 사용자 이미지를 표시하거나 웹 브라우저에서 URL을 열려면 암시적 인텐트를 사용하여 Android 시스템에 작업을 요청할 수 있습니다. 그런 다음 Android 시스템은 설치된 모든 애플리케이션에서 intent filters를 검색하고 적절한 컴포넌트를 비교하여 암시적 인텐트를 시작합니다. Android 시스템이 적절한 컴포넌트를 찾으면 사용 가능한 구성 요소 목록을 표시하지만, 그렇지 않은 경우 암시적 인텐트를 수행할 수 없습니다.

위의 이미지는 암시적 인텐트가 동작하는 방법을 보여줍니다. 더 자세한 내용은 Intents and Intent Filters를 참고해 주세요.

App Entry Points (앱 진입점)

Android에는 Activity와 앱 바로 가기라는 두 가지의 앱 진입점이 있습니다. 이전 섹션에서 활동에 대해 알아보았습니다. Activity의 상태 변경 및 백 스택 등에 대해 자세히 알고 싶다면 아래 자료를 확인하세요.

이제 App Shortcuts(앱 바로 가기)에 대해서 살펴보도록 하겠습니다.

App Shortcuts (앱 바로 가기)

앱 바로 가기를 사용하면 앱에서 특정 작업을 실행할 수 있습니다. 앱 아이콘을 길게 누르면 바로가기가 표시되고 아래 그림과 같이 목록에서 항목을 클릭하여 작업을 시작할 수 있습니다.

바로 가기에는 세 가지 유형이 있습니다.

  • Static shortcuts (정적 바로 가기): 정적 바로 가기는 앱 내에서 일관된 작업에 대한 링크를 제공하고 사용자 컨텍스트에 종속되지 않는 정적 작업을 수행합니다. (예: 최근 메시지 표시, 게시물 작성 또는 키워드 검색)

  • Dynamic shortcuts (동적 바로 가기): 동적 바로 가기는 앱 내 사용자 컨텍스트를 기반으로 하는 특정 작업에 대한 링크를 제공합니다. (예: 특정 사람에게 메시지를 보내거나 특정 위치로 이동)

  • Pinned shortcuts (고정된 단축키): 고정된 단축키(Android 8.0 이상에서 지원됨)를 사용하면 지원되는 실행기에 단축키를 고정할 수 있습니다. 홈 화면에서 고정된 바로 가기를 클릭하여 특정 작업을 실행할 수 있습니다.

다음 섹션에서는 가장 기본적인 Static shortcuts (정적 바로 가기)를 만드는 방법에 대하여 살펴보도록 하겠습니다.

Creating Static Shortcuts (정적 바로 가기 생성 하기)

정적 바로 가기를 생성하기 위해서는 아래와 같이 res/xml/shortcuts.xml 파일을 생성해야 합니다.

<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
  <shortcut
    android:shortcutId="message"
    android:enabled="true"
    android:icon="@drawable/ic_message"
    android:shortcutShortLabel="@string/short_label"
    android:shortcutLongLabel="@string/long_label"
    android:shortcutDisabledMessage="@string/message_shortcut_disabled">
    <intent
      android:action="android.intent.action.VIEW"
      android:targetPackage="com.example.myapplication"
      android:targetClass="com.example.myapplication.ComposeActivity" />
    <categories android:name="android.shortcut.conversation" />
    <capability-binding android:key="actions.intent.CREATE_MESSAGE" />
  </shortcut>
</shortcuts>

다음으로, 정의한 바로 가기를 사용하기 위해서 아래와 같이 App Manifest에 정의해야 합니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="io.getstream.example">
  <application ... >
    <activity android:name="Main">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      
      <meta-data android:name="android.app.shortcuts"
                 android:resource="@xml/shortcuts" /> 
    </activity>
  </application>
</manifest>

더 자세한 내용은 App shortcuts overview를 확인해 주세요.

Conclusion

이로써 2022 Android Developer Roadmap 2부 포스트를 마무리합니다. 이번 2부에서는 App components, lifecycles, 그리고 App entry points와 같이 중요한 부분에 대하여 살펴보았습니다.

다시 한 번 말씀드리지만, 로드맵의 방대한 양에 절대 당황하지마시고 학습에 필요한 부분만 선택적으로 학습하시는 것을 권장드립니다.

다음 포스트는 Stream 블로그에 가장 먼저 연재될 예정이며, 추후 velog에 번역본이 포스팅 될 예정입니다.

즐거운 코딩 되시길 바랍니다!

작성자 엄재웅 (skydoves)

profile
http://github.com/skydoves

0개의 댓글