λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Android

[Chap 2] μ•ˆλ“œλ‘œμ΄λ“œ μ•±μ˜ κΈ°λ³Έ ꡬ쑰

by nitronium102 2021. 11. 17.

μ•ˆλ“œλ‘œμ΄λ“œ μ†Œκ°œ

βœ¨μ•ˆλ“œλ‘œμ΄λ“œ : λ¦¬λˆ…μŠ€ 컀널을 기반으둜 κ΅¬κΈ€μ—μ„œ μ œμž‘ν•œ λͺ¨λ°”일 운영체제

1. μ•ˆλ“œλ‘œμ΄λ“œ 운영체제의 ꡬ쑰

1) λ¦¬λˆ…μŠ€ 컀널(Linux kernel) : μ•ˆλ“œλ‘œμ΄λ“œλŠ” λ¦¬λˆ…μŠ€ 기반 μ˜€ν”ˆμ†ŒμŠ€ μ†Œν”„νŠΈμ›¨μ–΄ μŠ€νƒμž„

2) ν•˜λ“œμ›¨μ–΄ 좔상화 λ ˆμ΄μ–΄(hardware abstraction layer, HAL) : ν•˜λ“œμ›¨μ–΄μ˜ 좔상화 κ³„μΈ΅μœΌλ‘œ, μƒμœ„μ˜ μžλ°” API ν”„λ ˆμž„μ›Œν¬μ—μ„œ ν•˜λ“œμ›¨μ–΄ κΈ°λŠ₯을 μ΄μš©ν•  수 있게 ν‘œμ€€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 제곡

3) μ•ˆλ“œλ‘œμ΄λ“œ λŸ°νƒ€μž„(Android runtime) : ART라고 ν•˜λ©°, 앱을 μ‹€ν–‰ν•˜λŠ” μ—­ν• 

μ•ˆλ“œλ‘œμ΄λ“œλŠ” μžλ°” 클래슀λ₯Ό λŸ°νƒ€μž„ λ•Œ κ·ΈλŒ€λ‘œ μ‹€ν–‰ν•˜μ§€ μ•Šκ³  DEX 파일둜 μ»΄νŒŒμΌν•œ ν›„, ARTμ—μ„œ μ‹€ν–‰ν•œλ‹€.

4) λ„€μ΄ν‹°λΈŒ C/C++ 라이브러리 : μžλ°” ν”„λ ˆμž„μ›Œν¬ 이외에도 λ„€μ΄ν‹°λΈŒ C/C++ 라이브러리λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€(μ•ˆλ“œλ‘œμ΄λ“œ NDK : native development kit)

5) μžλ°” API ν”„λ ˆμž„μ›Œν¬ : 앱을 κ°œλ°œν•  λ•Œ μ‚¬μš©ν•˜λŠ” μžλ°” API

 

2. μ•ˆλ“œλ‘œμ΄λ“œ 버전

- μ•ˆλ“œλ‘œμ΄λ“œ 버전(μ½”λ“œλͺ…) : 운영체제 버전

- API 레벨(SDK 버전) : 앱을 κ°œλ°œν•  λ•Œ μ‚¬μš©ν•˜λŠ” 버전 

운영체제 λ²„μ „λ³„λ‘œ API 레벨이 μ§€μ •λ˜μ–΄ μžˆμ–΄μ„œ μ†ŒμŠ€ μ½”λ“œμ—μ„œλŠ” λŒ€λΆ€λΆ„ API λ ˆλ²¨μ„ 이용

-> κ°œλ°œμžλŠ” 운영체제 버전과 API λ ˆλ²¨μ„ ν•¨κ»˜ μ•Œκ³  μžˆμ–΄μ•Ό 함

 

μ•ˆλ“œλ‘œμ΄λ“œ μ•± 개발의 νŠΉμ§• : μ»΄ν¬λ„ŒνŠΈ 기반 개발

μ»΄ν¬λ„ŒνŠΈ : μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ ꡬ성 μš”μ†Œ

- ν•˜λ‚˜μ˜ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ€ μ—¬λŸ¬ μ»΄ν¬λ„ŒνŠΈλ‘œ κ΅¬μ„±λ˜λ©°, μ΄λŸ¬ν•œ μ»΄ν¬λ„ŒνŠΈλŠ” 클래슀둜 κ°œλ°œλœλ‹€. 

 

1. μ•ˆλ“œλ‘œμ΄λ“œ 앱을 κ΅¬μ„±ν•˜λŠ” 클래슀

- μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ΅¬μ„±ν•˜λŠ” λͺ¨λ“  ν΄λž˜μŠ€κ°€ μ»΄ν¬λ„ŒνŠΈλŠ” μ•„λ‹˜

- 크게 μ•„λž˜ 두 클래슀둜 ꡬ뢄. λ‘˜ λ‹€ κ°œλ°œμžκ°€ λ§Œλ“œλŠ” ν΄λž˜μŠ€μ§€λ§Œ, λŸ°νƒ€μž„ λ•Œ 생λͺ…μ£ΌκΈ°λ₯Ό λˆ„κ°€ κ΄€λ¦¬ν•˜λŠ”κ°€μ— 따라 ꡬ뢄

 

1) μ»΄ν¬λ„ŒνŠΈ 클래슀

- 앱이 싀행될 λ•Œ 생λͺ…μ£ΌκΈ°λ₯Ό μ•ˆλ“œλ‘œμ΄λ“œ μ‹œμŠ€ν…œμ—μ„œ κ΄€λ¦¬ν•˜λŠ” 클래슀

2) 일반 클래슀

- 앱이 싀행될 λ•Œ 클래슀의 객체 생성뢀터 μ†Œλ©ΈκΉŒμ§€ 생λͺ…μ£ΌκΈ° 관리λ₯Ό 개발자 μ½”λ“œμ—μ„œ ν•˜λŠ” 클래슀

- κ°œλ°œμžκ°€ μž„μ˜μ˜ λͺ©μ μ„ 가지고 λ§Œλ“  클래슀

 

2. μ»΄ν¬λ„ŒνŠΈμ˜ μ’…λ₯˜

- μ§€μ •λœ μƒμœ„ 클래슀λ₯Ό 보고 κ΅¬λΆ„ν•œλ‹€.

 

1) μ•‘ν‹°λΉ„ν‹°(Activity 클래슀) : 화면을 κ΅¬μ„±ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈ. 앱이 μ‹€ν–‰λ˜λ©΄ μ•‘ν‹°λΉ„ν‹°μ—μ„œ 좜λ ₯ν•œ λ‚΄μš©μ΄ 화면에 λ‚˜μ˜΄.

2) μ„œλΉ„μŠ€(Service 클래슀) : λ°±κ·ΈλΌμš΄λ“œ μž‘μ—…μ„ ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈ.

3) μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”(ContentProvider 클래슀) : μ•±μ˜ 데이터λ₯Ό κ³΅μœ ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈ. μ•± 간에 데이터 곡유 κ°€λŠ₯

4) λΈŒλ‘œλ“œμΊμŠ€νŠΈ λ¦¬μ‹œλ²„(BroadcastReceiver 클래슀: μ‹œμŠ€ν…œ μ΄λ²€νŠΈκ°€ λ°œμƒν•  λ•Œ μ‹€ν–‰λ˜κ²Œ ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈ. 

* μ‹œμŠ€ν…œ 이벀트 : μ‹œμŠ€ν…œμ—μ„œ λ°œμƒν•˜λŠ” νŠΉμ • 상황 - λΆ€νŒ… μ™„λ£Œ, 배터리 λ°©μ „ λ“±μ˜ 상황

 

3. μ»΄ν¬λ„ŒνŠΈλŠ” μ•± μ•ˆμ—μ„œ λ…λ¦½λœ μ‹€ν–‰ λ‹¨μœ„

- μ»΄ν¬λ„ŒνŠΈλΌλ¦¬ μ„œλ‘œ μ’…μ†λ˜μ§€ μ•Šμ•„μ„œ μ½”λ“œ 결합이 λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.

- 두 클래슀λ₯Ό κ²°ν•©ν•΄μ„œ μ‹€ν–‰ν•˜λŠ” λ°©μ‹βŒ : μ»΄ν¬λ„ŒνŠΈμ˜ 생λͺ… μ£ΌκΈ°λ₯Ό μ•ˆλ“œλ‘œμ΄λ“œ μ‹œμŠ€ν…œμ—μ„œ κ΄€λ¦¬ν•˜λ―€λ‘œ μ½”λ“œμ—μ„œ 직접 객체λ₯Ό 생성해 μ‹€ν–‰ν•  수 μ—†μŒ.

- μ•ˆλ“œλ‘œμ΄λ“œ μ‹œμŠ€ν…œμ— 결합을 μ˜λ’°ν•΄ μ‹€ν–‰ν•˜λŠ” 방식⭕ : 두 ν΄λž˜μŠ€κ°€ μ„œλ‘œ μ’…μ†λ˜μ§€ μ•Šκ³  λ…λ¦½ν•΄μ„œ μ‹€ν–‰

(μ™Ό) 두 클래슀λ₯Ό κ²°ν•©ν•΄μ„œ μ‹€ν–‰ν•˜λŠ” 방식(λΆˆκ°€λŠ₯) (였) μ•ˆλ“œλ‘œμ΄λ“œ μ‹œμŠ€ν…œμ— 결합을 의뒰 

 

4. μ»΄ν¬λ„ŒνŠΈλ‘œ κ΅¬μ„±λœ μ•ˆλ“œλ‘œμ΄λ“œ μ•±μ˜ νŠΉμ§•

1) μ•±μ˜ μ‹€ν–‰ μ‹œμ μ΄ λ‹€μ–‘ : μ»΄ν¬λ„ŒνŠΈκ°€ μ•± λ‚΄μ—μ„œ λ…λ¦½ν•΄μ„œ μ‹€ν–‰λ˜κΈ° λ•Œλ¬Έ

2) μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 라이브러리 μ‚¬μš© : λ‹€λ₯Έ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ 라이브러리처럼 이용 κ°€λŠ₯

3) λ¦¬μ†ŒμŠ€ ν™œμš©

- λ¦¬μ†ŒμŠ€ : μ½”λ“œμ—μ„œ 정적인 값을 λΆ„λ¦¬ν•œ 것

- 같은 값을 맀번 μ‚¬μš©ν•œλ‹€λ©΄, μ½”λ“œμ— 담지 μ•Šκ³  λ¦¬μ†ŒμŠ€λ‘œ λΆ„λ¦¬ν•΄μ„œ 개발 -> 개발 생산성과 μœ μ§€λ³΄μˆ˜μ„± 증가

// λ¬Έμžμ—΄μ„ λ¦¬μ†ŒμŠ€λ‘œ λ“±λ‘ν•˜κΈ°
<string name="mytxt">
	동해 λ¬Όκ³Ό 백두산이 마λ₯΄κ³  닳도둝
    ν•˜λŠλ‹˜μ΄ λ³΄μš°ν•˜μ‚¬ μš°λ¦¬λ‚˜λΌ λ§Œμ„Έ
</string>
// λ¬Έμžμ—΄ λ¦¬μ†ŒμŠ€ μ‚¬μš© μ˜ˆμ‹œ
textView.text = resources.getString(R.string.mytxt)

 

μ•± ꡬ성 파일 뢄석

1. ν”„λ‘œμ νŠΈ 폴더 ꡬ쑰

- ν”„λ‘œμ νŠΈλ₯Ό λ§Œλ“€λ©΄ appμ΄λΌλŠ” λͺ¨λ“ˆμ΄ 생성

- ν•˜λ‚˜μ˜ λͺ¨λ“ˆ = ν•˜λ‚˜μ˜ μ•±(but μ—¬λŸ¬ λͺ¨λ“ˆλ‘œ λ‚˜λˆ„μ–΄ 생성 κ°€λŠ₯)

 

 

 

 

 

 

 

 

2. λͺ¨λ“ˆμ˜ 폴더 ꡬ성

이름 μ„€λͺ…
build.gradle λΉŒλ“œ μ„€μ • 파일
AndroidManifest.xml μ•±μ˜ 메인 ν™˜κ²½ 파일
res λ¦¬μ†ŒμŠ€ 폴더
activity_main.xml λ ˆμ΄μ•„μ›ƒ XML 파일
MainActivity.kt 메인 μ•‘ν‹°λΉ„ν‹° 파일

1) gradle λΉŒλ“œ μ„€μ • 파일

- gradle : μ•ˆλ“œλ‘œμ΄λ“œ μ•±μ˜ λΉŒλ“œ 도ꡬ

- build.gradle : gradle의 μ„€μ • 파일 -> 앱을 λΉŒλ“œν•˜λŠ”λ° ν•„μš”ν•œ 섀정을 이 νŒŒμΌμ— 등둝

- ν”„λ‘œμ νŠΈ μˆ˜μ€€μ˜ gradle(Project: AndroidLab)κ³Ό λͺ¨λ“ˆ μˆ˜μ€€μ˜ build.gradle(Module: AndroidLab.app) 쀑 ν›„μžμ— λŒ€λΆ€λΆ„μ˜ λΉŒλ“œ μ„€μ • μž‘μ„±

  • ν”ŒλŸ¬κ·ΈμΈ μ„€μ •
plugins { // 기본적으둜 μ•„λž˜ 두 개 μ„ μ–Έ, ν•„μš”μ— 따라 μΆ”κ°€ κ°€λŠ₯
	id 'com.android.application'
	id 'kotlin-android'
}
  • 컴파일 및 λΉŒλ“œ 버전 μ„€μ •
compileSdkVersion 30 // μ•ˆλ“œλ‘œμ΄λ“œ SDK 30 버전을 μ μš©ν•΄μ„œ μ»΄νŒŒμΌν•΄λΌ
buildToolsVersion "30.0.2"
  • μ•±μ˜ μ‹λ³„μž μ„€μ •(κ³ μœ ν•œ λ¬Έμžμ—΄)
applicationId "com.example.androidLab"
  • SDK 버전 μ„€μ •
minSdkVersion 16    // 이 앱을 μ„€μΉ˜ν•  수 μžˆλŠ” 기기의 μ΅œμ†Œ SDK 버전 
targetSdkVersion 30 // κ°œλ°œν•  λ•Œ μ μš©λ˜λŠ” SDK 버전
  • μ•±μ˜ 버전 μ„€μ •
versionCode 1 // μ΄ˆκΉƒκ°’μ€ 1μ΄μ§€λ§Œ μ„€μΉ˜ ν›„ μ—…λ°μ΄νŠΈ μ‹œ 버전 μ˜¬λ €μ„œ 배포
versionName "1.0"
  • 개발 μ–Έμ–΄μ˜ 버전 μ„€μ • : μžλ°” 버전 μ„ μ–Έ μƒλž΅ μ‹œ 기본적으둜 1.6 적용
compileOptions {
	sourceCompatibility JavaVersion.VERSION_1_8
    	targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
	jvmTarget = '1.8'
}
  • μ•±μ—μ„œ μ΄μš©ν•˜λŠ” 라이브러리의 버전 μ„€μ • : targetSDKVersion에 λͺ…μ‹œν•œ μ•ˆλ“œλ‘œμ΄λ“œ SDKλŠ” 기본으둜 μ μš©λ˜μ§€λ§Œ κ·Έ μ™Έμ˜ κ°œλ°œμžκ°€ μΆ”κ°€ν•˜λŠ” μ˜€ν”ˆ μ†ŒμŠ€ λΌμ΄λΈŒλŸ¬λ¦¬λ‚˜ κ΅¬κΈ€μ˜ androidx 라이브러리 λ“± SDK λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μ•„λ‹Œ μ™ΈλΆ€ λΌμ΄λΈŒλŸ¬λ¦¬λŠ” μ„ μ–Έ ν•„μš”
dependencies {
	implementation "org.jetbrains.kotlin::kotlin-stdlib:$kotlin_version"
    	implementation "androidx.core:core-ktx:1.3.2"
    	implementation "androidx.appcompat::appcompat::1.2.0'
}

 

2) 메인 ν™˜κ²½ 파일

- AndroidManifest.xml : μ•ˆλ“œλ‘œμ΄λ“œ μ•±μ˜ 메인 ν™˜κ²½ 파일(λ§€λ‹ˆνŽ˜μŠ€νŠΈ 파일). 이 파일 λ°”νƒ•μœΌλ‘œ μ‚¬μš©μžμ˜ ν°μ—μ„œ μ•± μ‹€ν–‰

  • λ„€μž„μŠ€νŽ˜μ΄μŠ€ μ„ μ–Έ
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidlab">

<manifest> : λ§€λ‹ˆνŽ˜μŠ€νŠΈ 파일의 루트 νƒœκ·Έ

- xmlns : XML의 λ„€μž„μŠ€νŽ˜μ΄μŠ€ μ„ μ–Έ

- URL : http://schemas.android.com/apk/res/android둜 μ„€μ •λ˜μ—ˆλ‹€λ©΄ μ•ˆλ“œλ‘œμ΄λ“œ ν‘œμ€€ λ„€μž„μŠ€νŽ˜μ΄μŠ€

- package : λ§€λ‹ˆνŽ˜μŠ€νŠΈ νŒŒμΌμ— μ„ μ–Έν•œ μ»΄ν¬λ„ŒνŠΈ 클래슀의 κΈ°λ³Έ νŒ¨ν‚€μ§€λͺ… -> 이후 λͺ¨λ“  κ²½λ‘œλŠ” νŒ¨ν‚€μ§€λͺ… 이후뢀터 μž‘μ„±

  • application νƒœκ·Έ 
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher" 		// res/map/ic_launcher.png
    android:label="@string/app_name" 		// res/values/strings.xml
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.AndroidLab"> 	// res/values/themes.xml

<application> : μ•± 전체λ₯Ό λŒ€μƒμœΌλ‘œ ν•˜λŠ” μ„€μ • νƒœκ·Έ

- xml의 속성값이 @둜 μ‹œμž‘ν•˜λ©΄ λ¦¬μ†ŒμŠ€λ₯Ό 의미

- icon : 앱을 μ‹€ν–‰ν•œ μ‚¬μš©μžμ˜ 폰에 λ³΄μ΄λŠ” μ‹€ν–‰ μ•„μ΄μ½˜

- label : μ•±μ˜ 이름 등둝 - res/values/strings.xml νŒŒμΌμ— app_name으둜 λ“±λ‘λœ λ¬Έμžμ—΄ λ¦¬μ†ŒμŠ€

- theme : 앱에 μ μš©ν•΄μ•Ό ν•˜λŠ” ν…Œλ§ˆ μ„€μ • - res/values/themes.xml νŒŒμΌμ— Theme.AndroidLab μ΄λ¦„μœΌλ‘œ μ„ μ–Έν•œ ν…Œλ§ˆ 적용

 

μ•ˆλ“œλ‘œμ΄λ“œ μ»΄ν¬λ„ŒνŠΈλŠ” μ‹œμŠ€ν…œμ—μ„œ 생λͺ…μ£ΌκΈ°λ₯Ό κ΄€λ¦¬ν•˜κ³ , μ‹œμŠ€ν…œμ€ λ§€λ‹ˆνŽ˜μŠ€νŠΈ νŒŒμΌμ— μžˆλŠ” λŒ€λ‘œ 앱을 μ‹€ν–‰ν•˜λ―€λ‘œ

μ•ˆλ“œλ‘œμ΄λ“œ μ»΄ν¬λ„ŒνŠΈλŠ” λ§€λ‹ˆνŽ˜μŠ€νŠΈ νŒŒμΌμ— 등둝해야 μ‹œμŠ€ν…œμ΄ 인지할 수 μžˆλ‹€!

  • μ•‘ν‹°λΉ„ν‹° μ„ μ–Έ
 <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>

- μ»΄ν¬λ„ŒνŠΈ ν•˜λ‚˜ λ‹Ή νƒœκ·Έ ν•˜λ‚˜

- name : ν•„μˆ˜ 속성 - 클래슀 이름 등둝 ex) name = ".MainActivity"

- <intent-filter> : μƒλž΅ κ°€λŠ₯ -> μ‚¬μš©μžκ°€ 앱을 μ„€μΉ˜ν–ˆμ„ λ•Œ μ•± μ•„μ΄μ½˜μ΄ λ‚˜μ˜€λŠ” μ—¬λΆ€ κ²°μ •(μ‚¬μš©μž μ‹€ν–‰ μ—¬λΆ€)

 

3) λ¦¬μ†ŒμŠ€ 폴더

res 폴더 : μ•±μ˜ λ¦¬μ†ŒμŠ€λ₯Ό λ“±λ‘ν•˜λŠ” λͺ©μ 

- drawable : 이미지 λ¦¬μ†ŒμŠ€

- layout : UI ꡬ성에 ν•„μš”ν•œ XML λ¦¬μ†ŒμŠ€

- mipmap : μ•± μ•„μ΄μ½˜ 이미지

- values : λ¬Έμžμ—΄ λ“±μ˜ κ°’μœΌλ‘œ μ΄μš©λ˜λŠ” λ¦¬μ†ŒμŠ€

 

μ•ˆλ“œλ‘œμ΄λ“œ λ¦¬μ†ŒμŠ€ 파일이 μ‚¬μš©λ˜λŠ” 원리

- res 폴더 μ•„λž˜μ— λ¦¬μ†ŒμŠ€λ₯Ό λ§Œλ“€λ©΄ μžλ™μœΌλ‘œ R.java νŒŒμΌμ— μƒμˆ˜ λ³€μˆ˜λ‘œ λ¦¬μ†ŒμŠ€κ°€ λ“±λ‘λ˜λ©°, μ½”λ“œμ—μ„œλŠ” 이 μƒμˆ˜ λ³€μˆ˜λ‘œ λ¦¬μ†ŒμŠ€λ₯Ό μ΄μš©ν•œλ‹€. R.javaλŠ” κ°œλ°œμžκ°€ λ§Œλ“œλŠ” 파일이 μ•„λ‹ˆλ©° res 폴더에 μžˆλŠ” λ¦¬μ†ŒμŠ€λ₯Ό 보고 μžλ™μœΌλ‘œ λ§Œλ“€μ–΄μ§„λ‹€. λ”°λΌμ„œ κ°œλ°œμžλŠ” 이λ₯Ό 확인할 수 μ—†λ‹€!

 

λ¦¬μ†ŒμŠ€ 폴더 κ·œμΉ™

- res ν•˜μœ„μ˜ 폴더λͺ…은 μ§€μ •λœ 폴더λͺ…을 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€. (개발자 μž„μ˜μ˜ 폴더 μ‚¬μš© λΆˆκ°€)

ex) 이미지 - drawable 폴더, UI κ΄€λ ¨ XML 파일 - layout 폴더

- 각 λ¦¬μ†ŒμŠ€ 폴더에 λ‹€μ‹œ ν•˜μœ„ 폴더λ₯Ό μ •μ˜ν•  수 μ—†λ‹€. 

- λ¦¬μ†ŒμŠ€ 파일λͺ…은 μžλ°”μ˜ 이름 κ·œμΉ™μ„ μœ„λ°°ν•  수 μ—†λ‹€. (R.java νŒŒμΌμ— λ³€μˆ˜λͺ…μœΌλ‘œ μ‚¬μš©λ˜κΈ° λ•Œλ¬Έ) - 숫자 μ‹œμž‘ λΆˆκ°€

- λ¦¬μ†ŒμŠ€ 파일λͺ…은 μ•ŒνŒŒλ²³ λŒ€λ¬Έμžλ₯Ό μ΄μš©ν•  수 μ—†λ‹€. - 두 단어 μ—°κ²° μ‹œ two_words처럼 밑쀄 이용

 

4) λ ˆμ΄μ•„μ›ƒ XML 파일

- 화면을 κ΅¬μ„±ν•˜λŠ” XML 파일

<androidx.constriantlayout.widget.ConstraintLayout> : λ ˆμ΄μ•„μ›ƒ μ±•ν„°μ—μ„œ μžμ„Ένžˆ 닀룬닀

<textView> : 화면에 λ¬Έμžμ—΄μ„ 좜λ ₯ν•˜λŠ” μ—­ν• 

 

5) 메인 μ•‘ν‹°λΉ„ν‹° 파일

λ§€λ‹ˆνŽ˜μŠ€νŠΈ 파일의 섀정값에 따라 폰에 앱을 μ„€μΉ˜ν•œ ν›„ μ•± μ•„μ΄μ½˜μ„ ν„°μΉ˜ν•˜λ©΄ MainActivity.kt μ‹€ν–‰

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

- AppCompatActivityλ₯Ό 상속받아 λ§Œλ“  클래슀 : ν™”λ©΄ 좜λ ₯을 λͺ©μ μœΌλ‘œ ν•˜λŠ” μ•‘ν‹°λΉ„ν‹° 클래슀

- MainActivity ν•¨μˆ˜ μ‹€ν–‰ μ‹œ onCreate() ν•¨μˆ˜ μžλ™ 호좜

-> setContentView() ν•¨μˆ˜ : λ§€κ°œλ³€μˆ˜μ— μ§€μ •ν•œ λ‚΄μš©μ„ μ•‘ν‹°λΉ„ν‹° 화면에 좜λ ₯

-> R.layout.activity_main - res/layout/activity_main.xml νŒŒμΌμ— κ΅¬μ„±λœ λ‚΄μš©μ„ 화면에 좜λ ₯

λŒ“κΈ€