안드로이드

[안드로이드] Android 4대 컴포넌트 (+ Kotlin Activity 생명주기 예제코드)

권송미 2024. 8. 24. 17:23
728x90
반응형

 

 

 

 

 

 

 

 

 

안드로이드는 4대 컴포넌트가 있습니다. 

각 구성요소는 시스템이나 사용자가 앱에 진입할 수 있는 진입점입니다.

 

 

 

Activities, Services, Broadcase Recievers, Content Prviders 로 구성되어 있습니다.

 

 

각 유형마다 용도가 정해져있고, 각 구성요소는 생성 및 소멸 방식을 정의하는 고유한 수명 주기가 있습니다.

 

 

 

 

 

 

 

 

1. Activities

 

- 안드로이드의 메이져 컴포넌트로, 사용자와 상호작용하기 위한 진입점입니다.

- 사용자 인터페이스(UI)를 제공하는 컴포넌트입니다.

- 예 ) 로그인 화면, 설정 화면, 홈 화면 등 ...

 

 

 

- AndroidManifest.xml 에서 보면 <activity>에 있는 Activities를 볼 수 있습니다.

 <intent-filter>를 통해 앱이 수신할 수 있는 암시적 인텐트를 알려줍니다  -> 앱의 진입점을 정의

<manifest ...>
    <application ...>
        <activity
            android:name=".ExampleActivity" />
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

 

 

 

 

 

 

 

 

Activity에는 생명주기가 있습니다.

생명주기는 앱에서 액티비티가 생성되고 소멸되는 인련의 상태 변화를 말합니다.

이 생명주기를 통해 사용자가 앱과 상호작용하는 동안 앱의 상태를 관리하고, 리소스를 효율적으로 사용하도록 도와줍니다.

 

 

 

수명주기 특징은, 아래와 같습니다.

 

- onCreate()

  • 역할 : 액티비티가 처음 생성될 때 호출
  • 특징 : 액티비티가 새로 생성될 때 한 번만 호출

- onStart()

  • 역할 : 액티비티가 화면에 나타나기 직전에 호출
  • 특징 : UI와 관련된 리소스 초기화가 필요할 때 사용

- onResume()

  • 역할 : 액티비티가 사용자와 상호작용할 준비가 되었을 때 호출
  • 특징 : 앱이 완전히 활성화된 상태로, 사용자의 모든 작업이 이 단계에서 수행

- onPause()

  • 역할 : 액티비티가 일시 중지될 때 호출
  • 특징 : 액티비티가 부분적으로 보일 수 있지만, 사용자 입력은 받지 않음

- onStop()

  • 역할 : 액티비티가 사용자에게 더 이상 보이지 않을 때 호출
  • 특징 : 액티비티가 Stopped 상태가 됌

- onDestroy()

  • 역할 : 액티비티가 종료되기 직전에 호출
  • 특징 : 액티비티가 완전 소멸될 때 호출, 시스템이 메모리 회수를 위해 액티비티를 제거하는 경우에도 호출

- onRestart()

  • 역할 : onStop() 이후, 다시 액티비티가 시작되기 전에 호출
  • 특징 : onStart() 전에 호출, onStop()에서 해제된 리소스를 다시 로드할 때 사용

 

 

 

 

 

 

 

간단한 예제로 수명주기를 이해해봅시다.

 

 

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() {

    private val TAG = "Lifecycle"

    // 액티비티가 생성될 때 호출됨
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d(TAG, "onCreate called")
    }

    // 액티비티가 사용자에게 보이기 시작할 때 호출됨
    override fun onStart() {
        super.onStart()
        Log.d(TAG, "onStart called")
    }

    // 액티비티가 상호작용 가능한 상태가 될 때 호출됨
    override fun onResume() {
        super.onResume()
        Log.d(TAG, "onResume called")
    }

    // 다른 액티비티가 포그라운드로 올라와 이 액티비티가 일시 중지될 때 호출됨
    override fun onPause() {
        super.onPause()
        Log.d(TAG, "onPause called")
    }

    // 액티비티가 더 이상 사용자에게 보이지 않을 때 호출됨
    override fun onStop() {
        super.onStop()
        Log.d(TAG, "onStop called")
    }

    // 액티비티가 중지된 후 다시 시작되기 전에 호출됨
    override fun onRestart() {
        super.onRestart()
        Log.d(TAG, "onRestart called")
    }

    // 액티비티가 종료되거나 시스템에 의해 제거될 때 호출됨
    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "onDestroy called")
    }
}

 

 

 

 

 

-시작

 

 

위처럼 코드를 적고 앱을 실행하면 이렇게 순서대로 로그가 찍히는 것을 볼 수 있습니다.

 

 

 

 

 

 

- 다시 시작

 

 

앱을 내리고 다시 앱을 시작하면 onRestart() -> onStart() -> onResume() 순대로 로그가 찍힙니다.

 

 

 

 

 

 

 

- 종료

 

앱을 내리고(일시중지) 날리면(종료) 이렇게 로그가 찍히는 것을 볼 수 있습니다.

앱을 내리면 일시중지가 되어 onPause() -> onStop()이 뜨고 앱을 날리는 순간 onDestroy()가 호출됩니다.

 

 

 

 

 

 

간단히 순서를 정리하자면, 아래처럼 정리할 수 있습니다 !

 

 

- 시작 : onCreate() -> onStart() -> onResume()

- 다시 시작 : onRestart() -> onStart() -> onResume()

- 일시중지 : onPause() -> onStop()

- 종료 : onPause() -> onStop() -> onDestroy()

 

 

시작과 다시시작은  _____ -> onStart() -> onResume() 상태로 맨앞 상태주기만 변하며, 

일시중지와 종료는 onPause() -> onStop() 은 일정하고 onDestroy()가 있냐 없냐의 차이입니다.

 

 

 

 

 

 

 

 

 

 

2. Services

 

- 백그라운드에서 실행되는 작업을 수행하는 컴포넌트입니다.

- 사용자와 상호작용을 할 수 없지만, 음악재생, 네트워크 요청 처리, 데이터베이스 연산 등과 같은 작업을 처리합니다.

- Service는 'Started Service'와 'Bound Service' 로 나뉩니다.

- Started Service는 특정 작업이 완료될 때까지 계속 실행되며, Bound Service는 다른 컴포넌트와의 바인딩을 통해 실행됩니다.

- Foreground Service,  Background Service -> Started Service의 일종

 

 

 

class MainActivity : AppCompatActivity() {

    private val TAG = "Lifecycle"

    // 액티비티가 생성될 때 호출됨
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d(TAG, "onCreate called")

        val serviceIntent = Intent(this, MyService::class.java)
        startService(serviceIntent)
    }
    ...
  }

 

 

 

Activity onCreate에서 Intent()로 startService()라고 해야 하며,

 

 

 

AndroidManifest.xml에서 아래처럼 <service>를 추가해주어야 합니다.

<manifest ...>
    <application ...>
        <activity
            android:name=".ExampleActivity" />
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <service android:name=".MyService"/>
    </application>
</manifest>

 

 

 

 

 

 

3. Broadcase Recievers

 

- 시스템 전체에서 발생하는 이벤트 또는 다른 앱에서 발생한 이벤트에 반응하는 컴포넌트입니다.

- 예 ) 배터리 상태 변화, 네트워크 연결 상태 등

- AndroidManifest.xml에서 <receiver>로 추가해주어야 합니다.

 

 

 

예제 코드

 

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.Toast

class MyBroadcastReceiver: BroadcastReceiver() {

    override fun onReceive(p0: Context?, p1: Intent?) {
        Log.d("MyBroadcastReceiver", "Broadcast Received!")
        if (p0 != null) {
            Toast.makeText(p0, "Broadcast Received!", Toast.LENGTH_SHORT).show()
        }
    }
}

 

 

브로드캐스터리시버를 상속받은 클래스를 생성해줍니다.

 

 

 

 

 

 

AndroidManifest.xml에 아래처럼 추가해줍니다.

        <receiver
            android:name=".MyBroadcastReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.a4components.CUSTOM_ACTION"/>
            </intent-filter>
        </receiver>

 

 

 

 

 

 

MainActivity.kt에서 아래처럼 테스트 버튼을 추가해서 예제를 만들면 

 

import android.content.Intent
import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button

class MainActivity : AppCompatActivity() {

    private val TAG = "Lifecycle"
    private lateinit var myReceiver: MyBroadcastReceiver

    // 액티비티가 생성될 때 호출됨
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d(TAG, "onCreate called")

        myReceiver = MyBroadcastReceiver()
        val filter = IntentFilter("com.example.a4components.CUSTOM_ACTION")
        registerReceiver(myReceiver, filter)

        val sendButton = findViewById<Button>(R.id.testButton)
        sendButton.setOnClickListener {
            val intent = Intent("com.example.a4components.CUSTOM_ACTION")
            sendBroadcast(intent)
        }
    }
}

 

 

 

 

 

 

MyBroadcastReceiver 클래스에서 보낸 토스트가 뜨는 것을 볼 수 있습니다.

 

 

 

 

 

 

 

4. Content Prviders

 

- Android 앱 간에 데이터 공유를 할 수 있게 하는 컴포넌트입니다.

- 예) 연락처 앱에서 제공하는 데이터를 다른 앱에서 접근하여 사용, SQLite와 같은 DB나 파일 시스템 관리 등

- 보통 URI를 사용하여 데이터를 식별함

- 참고 : https://developer.android.com/guide/topics/providers/content-provider-basics

 

콘텐츠 제공자 기본사항  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 콘텐츠 제공자 기본사항 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 콘텐츠 제공자는 중앙 저장소

developer.android.com

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

참고

https://developer.android.com/guide/components/fundamentals

 

애플리케이션 기본 항목  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 애플리케이션 기본 항목 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Android 앱은 Kotlin, Java 프로그

developer.android.com

 

728x90
반응형