• 안드로이드 소개
  • 안드로이드 앱 개발의 특징
  • 앱 구성 파일 분석

02-1. 안드로이드 소개

안드로이드 운영체제의 구조

1. 리눅스 커널(Linux Kernel) - 리눅스에 기반을 둔 오픈소스 소프트웨어 스택입니다.

2. 하드웨어 추상화 레이어(Hardware Abstraction Layer, HAL) - 상위의 자바 API 프레임워크에서 하드웨어 기능을 이용할 수 있게 표준 인터페이스를 제공합니다.

예를들어, 앱에서 카메라나 위치정보가 필요한 경우 자바 API를 이용해 각 제조사(삼성, 화웨이, 샤오미 등)별로 다른 HAL에 맞춰 처리할 수 있습니다.

3. 안드로이드 런타임(Android Runtime) - ART라고하며 앱을 실행하는 역할을 합니다. 안드로이드 앱은 DEX파일로 빌드되는데, 이 DEX파일을 해석해서 실행하는 주체가 ART 입니다.

자바는 컴파일 이후 클래스파일이 만들어지고 이것을 자바 가상 머신(JVM)에서 실행하는데, 안드로이드는 런타임 때 그대로 실행하지않고 DEX파일로 컴파일하고 이를 ART에서 해석, 실행합니다.

4. 네거티브 C/C++ 라이브러리 - 안드로이드 앱은 대부분 자바 프레임워크로 개발하지만 네티이브 C/C++ 라이브러리를 이용할 수도 있는데 이를 안드로이드 NDK(Native Development Kit)이라고 합니다.

5. 자바 API 프레임워크 - 앱을 개발할 때 사용하는 자바 API 입니다.

 

안드로이드 버전

새로운 안드로이드 버전이 나오면 개발자는 변경사항을 잘 파악해 앱에 적용하는것이 중요합니다.

안드로이드 버전은 13.0, 14.0 처럼 운영체제 버전을 가리키지만, 앱을 개발할 때 사용하는 버전은 API레벨(SDK 버전) 입니다.

운영체제 버전별로 API레벨이 지정되어 있기 때문에 소스코드에서는 대부분 API레벨을 이용합니다.

따라서, 개발자는 운영체제 버전과 API레벨을 함께 알고 있어야 합니다.

 

02-1. 안드로이드 앱 개발의 특징

컴포넌트 기반의 개발

컴포넌트는 애플리케이션의 구성요소라고 할 수 있습니다.

애플리케이션이 아니라(X), 애플리케이션을 구성하는 단위로 하나의 애플리케이션은 여러 컴포넌트로 구성됩니다.

컴포넌트의 형태는 상황에 따라 달라지는데 JAR이나 DLL로도 개발합니다.

안드로이드에서는 클래스로 컴포넌트를 개발합니다. 하나의 클래스가 하나의 컴포넌트가 되는 것입니다.

 

하지만 모든 클래스가 컴포넌트인 것은 아닙니다. 컴포넌트 클래스와 일반 컴포넌트로 구분됩니다.

생명주기 관리를 개발자 코드에서 한다면: 일반클래스(객체를 생성하거나 참조하며 코드에서 관리되는 경우)

생명주기를 안드로이드 시스템에서 관리한다면: 컴포넌트 클래스 (메모리 부족 등의 이유로 시스템이 생명주기를 관리하는 경우 예: 백그라운드 음악재생 등)

 

안드로이드 컴포넌트는 크게 4종류가 있습니다.

1. 액티비티: 화면을 구성하는 컴포넌트

2. 서비스: 백그라운드 작업을 하는 컴포넌트

3. 컨텐츠 프로바이더: 앱의 데이터를 공유하는 컴포넌트(앱간 데이터를 공유하는 경우 예: 카톡에서 프로필 변경을 위해 갤러리 앱 접근 등)

4. 브로드캐스트 리시버: 시스템 이벤트가 발생할 때 실행되는 컴포넌트(부팅 완료, 배터리 방전 등)

 

컴포넌트의 구분과 구성

컴포넌트는 앱이 실행될 때 안드로이드 시스템에서 생명주기를 관리하지만 개발자가 만들어야 하는 클래스입니다.

이를 만들기 이위해 지정된 클래스를 상속받는데 Activity 클래스를 상속받으면 액티비티 컴포넌트, 같은 방식으로 Service, ContentProvider, BroadcastReceiver를 상속받는 경우 해당 컴포넌트 클래스로 구분 지을 수 있습니다.

 

구성은 개발자가 만들고자 하는 앱의 기능과 화면 등을 고려해 필요한 만큼 구성하면 됩니다.

설계에 따라 달라지며 정해진 규칙은 없습니다.

(화면을 제공하지 않는 앱도 개발할 수 있습니다.)

 

컴포넌트는 앱 안에서 독립된 실행 단위이다.

카카오톡의 목록 화면과 채팅을 예로들겠습니다.

채팅방 목록 화면은 ListActivity라는 클래스명으로, 채팅 화면은 ChatActivity라는 클래스로 작성해 화면 전환을 한다고 가정합ㄴ디ㅏ.

ListActivity에서 ChatActivity객체를 생성해 실행하는 것은 안드로이드에서 불가능 합니다.

따라서 안드로이드 시스템에 의뢰해 두 클래스가 서로 종속되지 않고 독립해서 실행되게 해야 합니다.

 

따라서 다양한 앱 실행 시점에 대처가 가능하다.

카카오톡을 켜고 채팅창을 여는 방법이 있지만, 카카오톡 알림을 눌러 채팅창을 바로 열기도 합니다.

컴포넌트각 독립되어 실행되기 때문에 가능합니다.

 

애플리케이션 라이브러리를 사용할 수 있다.

카카오톡에서 사진을 즉석에서 찍어 공유하기 위해 카카오톡 → 카메라 → 카카오톡 순으로 카메라 앱을 라이브러리처럼 이용할 수 있습니다.

 

리소스를 활용한 개발이 가능하다.

리소스란 코드에서 정적인 값을 분리한 것입니다. 사용자 이벤트에 따라 동적인 값이 아니라 항상 같은 값이라면 굳이 코드에 담지 않고 분리해서 개발할 수 있습니다.

화면에 애국가 가사를 출력한다면, 애국가 가사를 저장해두고 리소스처럼 등록해 언제든 간편하게 사용할 수 있습니다.

이 외에 색상, 크기, 레이아웃, 이미지, 메뉴 등 많은 요소를 리소스로 활용할 수 있습니다. 이미지 등 몇몇을 제외하면 대부분 리소스는 XML로 작성해 활용합니다.

 

02-3. 앱 구성 파일 분석

프로젝트의 폴더 구성

프로젝트를 만들면 app이라는 모듈이 자동으로 생성되며 모듈 하나가 앱 하나(원한다면 하나의 앱을 여러 모듈로 나눠 개발 가능)이며 프로젝트는 여러 모듈을 묶어서 관리하는 개념입니다.

 

모듈의 폴더 구성

build.gradle.kts: 빌드 설정 파일

AndroidManifest.xml: 앱의 메인 환경 파일

res: 리소스 폴더

activity_main.xml: 레이아웃 xml 파일

MainActivity.kt: 메인 액티비티 파일

 

그래들 빌드 설정 파일

안드로이드 앱의 빌드 도구 입니다. [Gradle Scripts]에서 찾을 수 있습니다.

파일이 두개가 있는데 하나는 프로젝트 수준의 build.gradle.kts이고, 다른 하나는 모듈 수준의 build.gradle.kts입니다.

모듈은 앱을 의미하므로 대부분의 빌드 설정은 모듈 수준의 그래들 파일에 작성합니다.

 

리소스 폴더

앱의 리소스를 등록하는 목적으로 사용됩니다.

drawble: 이미지 리소스

layout: UI 구성에 필요한 XML 리소스

mipmap: 앱 아이콘 이미지

values: 문자열 등의 값으로 이용되는 리소스

 

res폴더 아래에 리소스를 만들면 자동으로 R.java 파일에 상수 변수로 리소스가 등록되며, 코드에서는 이 상수 변수로 리소스를 이용합니다.

res/drawble폴더에 person1.png파일을 등록했다면 이를 식별하기위한 int형 변수가 R.java에 등록되고 R.drawble.person1과 같은 형식으로 식별됩니다.

이는 다음과 같은 규칙을 갖습니다.

1. res 하위의 폴더명은 지정된 폴더명을 사용해야 합니다.

2. 각 리소스 폴더에 다시 하위폴더를 정의할 수는 없습니다.

3. 리소스 파일명은 자바의 이름 규칙을 위배할 수 없습니다. (숫자로 시작할 수 없음 등)

4. 리소스 파일명에는 알파벳 대문자를 이용할 수 없습니다. (addUser.xml 대신 add_user.xml으로 정의하는것이 일반적)

 

레이아웃 XML 파일

res/layout폴더 아래에 기본으로 만들어지는 activity_main.xml파일은 화면을 구성하는 레이아웃 XML파일입니다.

화면을 구성하는 요소로만 알아두고 화면을 프로그래밍 하는 방법에 대해 알아볼때 다룹니다.

 

메인 액티비티 파일

package com.example.androidlab

import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat

//  메인 액티비티 파일
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
    }
}

AppCompatActivity를 상속받아 정의되어있습니다. AppCompatActivity는 Activity의 하위 클래스입니다. 따라서 MainActivity는 액티비티 컴포넌트 클래스입니다. 화면 출력을 목적으로 하는 액티비티 클래스라는 의미입니다.

 

MainActivity클래스 실행 → onCreate()함수 호출

이 때 setContentView() 함수는 매개변수에 지정한 내용을 액티비티 화면에 출력합니다. R.layout.activity_main이 지정되어 res/layout/activity_main.xml 파일에 구성한 내용을 화면에 출력합니다.

enableEdgeToEdge()함수는 상단의 배터리표시가 있는 영역(Status Bar)와 하단 버튼 영역(Navigation Bar)까지 나오게 하는 설정입니다.

setOnApplyWindowInsetsListener()함수는 출력되는 내용이 NavigationBar등과 겹치지 않게 하기 위한 설정입니다.

이 두 함수는 자동으로 작성되어있지만 필요없다면 제거해도 됩니다.

 

 

'Java > Kotlin' 카테고리의 다른 글

Kotlin Programming Study - 07  (0) 2025.12.16
Kotlin Programming Study - 06  (0) 2025.12.15
Kotlin Programming Study - 04  (0) 2025.12.10
Kotlin Programming Study - 03  (0) 2025.12.09
Kotlin Programming Study - 01  (0) 2025.12.05

+ Recent posts