깨알 개념/Android

[Android] Dagger2 - Application 활용하기

interfacer_han 2024. 6. 25. 09:12

#1 이전 글

[Android] Dagger2 - 기초

#1 이전 글 의존성 주입 (Dependency Injection)#1 의존성 주입(Dependency Injection)이란?#1-1 Dependent와 Dependencyfun main() { val car = Car() car.startCar() } class Car { private val engine = Engine() private val airbag = Airbag() private

kenel.tistory.com

위 게시글의 완성된 앱을 일부 수정해서, Application을 활용하게 만든다. 이를 통해, @Component 클래스 인스턴스의 중복 호출을 제거한다.
 

#2 Application의 활용성

Application  |  Android Developers

developer.android.com

애플리케이션 클래스는 안드로이드 앱의 기본 클래스로 모든 Activity의 생성 전에 생성되는 최상위 객체이기도 하다. Application은 앱의 전역에서 유일하게(= 싱글톤) 실행되는 클래스라는 특징이 있다. 그리고 이 특징을 dagger를 사용할 때 쏠쏠히 이용할 수 있다.
 
이전 글에서는 MainActivity로부터 @Component 클래스의 객체를 생성해서 Car 객체를 얻었다. 이 때, 실제 안드로이드 앱에서 여러 개의 Activity가 존재하는 상황이라면, 그 갯수만큼 @Component 클래스의 인스턴스를 얻어야할 것이다. 즉 코드의 중복이 발생한다. 이 중복되는 동작을 해결하는 좋은 방법 중 하나가 바로 해당 @Component 인스턴스를 Application 객체에 정의하는 것이다. 
 

#3 코드 수정

#3-1 개요

이제, Application 클래스를 상속받아 사용자 정의 Application 클래스를 만들고, 기본 Application 대신 사용자 정의 Application 클래스가 실행되게 만들어보겠다.
 

#3-2 MyApplication.kt 생성

// package com.example.useapplication

import android.app.Application

class MyApplication : Application() {
    lateinit var carComponent: CarComponent

    override fun onCreate() {
        super.onCreate()
        carComponent = initDagger()
    }

    private fun initDagger(): CarComponent {
        return DaggerCarComponent.create()
    }
}

 

#3-3 AndroidManifest.xml 수정

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:name=".MyApplication"
        ...
    </application>

</manifest>

<application> 클래스의 android:name 속성을 추가한다. 이 속성은 앱의 기본 Application 클래스를 지정한다. 여기에 방금 만들었던 MyApplication 클래스를 할당한다. 이제, Dagger의 Component 클래스를 Application에 초기화하여 전역적으로 사용할 준비가 끝났다.
 
여담으로, 안드로이드 프로젝트를 만들면 <application>의 android:name 속성은 기본적으로 생략되어있다. 이 경우 안드로이드 시스템은 기본 Application 클래스를 사용한다. 매우 간단해서 전역적인 초기화 작업이나 상태 관리가 필요하지 않은 앱은 android:name 속성을 생략해도 된다. 
 

#3-4 MainActivity.kt 수정

// package com.example.useapplication

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

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedState: Bundle?) {
        super.onCreate(savedState)
        setContentView(R.layout.activity_main)
/*
        ...
*/
        /* application을 get하고 MyApplication으로 타입 캐스팅.
         * 타입 캐스팅의 이유:
         * application 객체는 기본적으로 Application 타입으로 제공되지만,
         * 실제로는 MyApplication 클래스의 인스턴스이기 때문이다.
         */
        val car = (application as MyApplication).carComponent.getCar()
        car.startCar()
    }
}

 

#4 작동 확인 (로그 메시지)

Crankshaft is ready
Cylinder is ready
Piston is ready
Engine is ready
Airbag is ready
Battery is ready
Car is ready

 

#5 요약

Application의 활용은 일종의 싱글톤 기법이라고도 볼 수 있다.
 

#6 완성된 앱

android-practice/dagger2/UseApplication at master · Kanmanemone/android-practice

Contribute to Kanmanemone/android-practice development by creating an account on GitHub.

github.com