728x90

๊ฐœ๋ฐœ/Android 19

[Android Studio] MacOS Big Sur 11.3์—์„œ ์•ˆ๋“œ๋กœ์ด๋“œ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์„ ๋•Œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

์ตœ๊ทผ MacOS๋ฅผ Big Sur๋กœ ์—…๋ฐ์ดํŠธํ•˜๊ณ ๋‚˜์„œ ์•ˆ๋“œ๋กœ์ด๋“œ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. ์ฐพ์•„๋ณด๋‹ˆ Android emulator ์ตœ์‹  ๋ฒ„์ „์—์„œ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ, ์—…๋ฐ์ดํŠธ ํ›„์—๋„ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์•„ ์•„๋ž˜ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐํ–ˆ๋‹ค. ์›์ธ์€ ์• ํ”Œ์ด hypervisor entitlement(๊ถŒํ•œ ๊ด€๋ จ?)๋ฅผ 'com.apple.vm.hypervisor'์—์„œ 'com.apple.security.hypervisor'๋กœ ๋ณ€๊ฒฝํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ํ•œ๋‹ค. 1. entitlements.xml ํŒŒ์ผ ์ƒ์„ฑ com.apple.security.hypervisor 2. ํ„ฐ๋ฏธ๋„์—์„œ ์•„๋ž˜ ์ปค๋งจ๋“œ ์‹คํ–‰ codesign -s - --entitlements entitlements.xml --force ~/Library/Andro..

[Android] unit test์—์„œ android Util ์‚ฌ์šฉํ•˜๊ธฐ

Unit test์—์„œ android Utils๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ, ์•„๋ž˜์™€ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, TextUtils.isEmtpy()๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒฝ์šฐ java.lang.RuntimeException: Method isEmpty in android.text.TextUtils not mocked ๋ฐฉ๋ฒ•1) app์˜ build.gralde์— ์˜ต์…˜ ์ถ”๊ฐ€ android { // ... testOptions { unitTests.returnDefaultValues = true } } -> ์ฃผ์˜ : Default๊ฐ’์ด ๋ฐ˜ํ™˜๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์˜ˆ์ƒํ•œ ๋™์ž‘๊ณผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค. ๋ฐฉ๋ฒ•2) src/test/java > android. ํŒจํ‚ค์ง€์— ๋™์ผํ•œ Utils ํด๋ž˜์Šค ์ถ”๊ฐ€ ์˜ˆ์‹œ) TextUtils..

[Android Studio] Wi-Fi ํ™˜๊ฒฝ์—์„œ ์œ ์„  ์—ฐ๊ฒฐ์—†์ด ๋””๋ฒ„๊น…ํ•˜๊ธฐ

์ž‘์„ฑ์ผ: 2020.03.20 Wi-Fi ํ™˜๊ฒฝ์—์„œ ์œ ์„  ์—ฐ๊ฒฐ์—†์ด ๋ฌผ๋ฆฌ ๋””๋ฐ”์ด์Šค์— ์•ฑ ์‹คํ–‰ ๋ฐ ๋””๋ฒ„๊น… ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ตœ๊ทผ์— ๊ธฐ๊ธฐ์— USB ๋“œ๋ผ์ด๋ธŒ๊ฐ€ ์—ฐ๊ฒฐ๋œ ์ƒํƒœ์—์„œ ๋””๋ฒ„๊น…์ด ํ•„์š”ํ•ด์„œ ์ฐพ์•„๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค. ๋„ˆ๋ฌด ๊ฐ„๋‹จํ•ด์„œ Toast Message๋กœ ํž˜๋“ค๊ฒŒ ๋””๋ฒ„๊น…ํ–ˆ๋˜ ๊ฒƒ์ด ํ—ˆ๋ฌดํ•˜์ง€๋งŒ..๐Ÿฅด ์žŠ์–ด๋ฒ„๋ฆฌ์ง€ ์•Š๊ณ  ๋‚˜์ค‘์—๋„ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ์ ์–ด๋‘”๋‹ค! ๊ฐ™์€ ๋„คํŠธ์›Œํฌ์— ์—ฐ๊ฒฐ์ด ๋˜์–ด ์žˆ๋‹ค๋ฉด, ๊ฐ„๋‹จํ•œ ์„ค์ •์œผ๋กœ ๋ฌด์„  ๋””๋ฒ„๊น…์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์ˆœ์„œ Android ๋””๋ฐ”์ด์Šค๋ฅผ USB ์ผ€์ด๋ธ”๋กœ ์œ ์„  ์—ฐ๊ฒฐํ•œ๋‹ค. (์ฒ˜์Œ์—” USB ์ผ€์ด๋ธ”๋กœ ์œ ์„  ์—ฐ๊ฒฐ์ด ํ•„์š”ํ•˜๋‹ค) platform-tools๋กœ ์ด๋™ํ•˜์—ฌ adb tcpip 5555 ์ปค๋งจ๋“œ ์ž…๋ ฅ adb ์ปค๋งจ๋“œ๋ฅผ ๋ฏธ๋ฆฌ ์„ค์ •ํ•ด๋†“์œผ๋ฉด ๊ตณ์ด ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™ํ•˜์ง€ ์•Š์•„๋„ ๋ผ์„œ ํŽธ๋ฆฌํ•˜๋‹ค. adb connect :5555 ์ปค๋งจ๋“œ ์ž…..

[Android] Dependency Injection Part 3. Dagger basics

์ž‘์„ฑ์ผ: 2020.03.02 ์ด ๊ธ€์€ Android Developer ๊ฐ€์ด๋“œ ๋‚ด์šฉ์„ ํ† ๋Œ€๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ ์ฝ”๋“œ๋Š” Kotlin๋งŒ ๊ฐ€์ ธ์™”์œผ๋ฉฐ, Java ์ฝ”๋“œ๋Š” ์›๋ฌธ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง์ ‘ ์˜์กด์„ฑ ์ฃผ์ž…์ด๋‚˜ Service locator ์‚ฌ์šฉ์€ ํ”„๋กœ์ ํŠธ ํฌ๊ธฐ์— ๋”ฐ๋ผ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Dagger๋ฅผ ์‚ฌ์šฉํ•ด ๋””ํŽœ๋˜์‹œ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉด ํ”„๋กœ์ ํŠธ์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋”๋ผ๋„ ๋ณต์žก์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Dagger์˜ ์žฅ์  Dagger๋Š” ๋ฒˆ๊ฑฐ๋กญ๊ณ  ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฌ์šด ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š๋„๋ก ์•„๋ž˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Part 2์—์„œ ์ง์ ‘ ๊ตฌํ˜„ํ–ˆ๋˜ AppContainer ์ฝ”๋“œ(application graph) ์ƒ์„ฑ Application graph์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํด๋ž˜์Šค๋“ค์— ๋Œ€ํ•œ ํŒฉํ† ๋ฆฌ ์ฝ”๋“œ ์ƒ์„ฑ โž” ..

[Android] ExoPlayer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ๊ฐ„๋‹จ ์˜ค๋””์˜ค ํฌ์ปค์Šค ์ฒ˜๋ฆฌํ•˜๊ธฐ

์ž‘์„ฑ์ผ: 2020.03.02 ๋ฐฉ๋ฒ• ExoPlayer๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ handleAudioFocus ํ”Œ๋ž˜๊ทธ ๊ฐ’์„ true๋กœ ์ฃผ๋ฉด ๋œ๋‹ค. exoPlayer.setAudioAttributes(new AudioAttributes.Builder() .setContentType(C.CONTENT_TYPE_MUSIC) .setUsage(C.USAGE_MEDIA) .build(), /*handleAudioFocus = */ true); -๋- Note ExoPlayer์™€ MediaSessionConnector๋ฅผ ํ•จ๊ป˜ ์“ธ ๋•Œ, MediaSessionConnector ๋‚ด๋ถ€์—์„œ ๋ณ„๋„๋กœ MediaSession.Callback์„ ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ Service ์•ˆ์—์„œ MediaSession์— Callback์„ ์ถ”๊ฐ€..

[Android] MediaBrowser.connect() ์•„๋ฌด ๋ฐ˜์‘์ด ์—†์„ ๋•Œ

์ž‘์„ฑ์ผ: 2020.02.13 MediaBrowser.connect() ํ˜ธ์ถœํ•ด๋„ ์•„๋ฌด ๋ฐ˜์‘์ด ์—†์„ ๋•Œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ์ด์Šˆ ๋‚ด์šฉ MediaBrowser.connect()๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•œ๋‹ค๋Š” ์•„๋ž˜ ๋กœ๊ทธ๊นŒ์ง€๋Š” ์ถœ๋ ฅ๋จ D/MediaBrowserCompat: Connecting to a MediaBrowserService. MediaBrowser๋Š” ์—ฐ๊ฒฐ ์ƒํƒœ์— ๋Œ€ํ•ด onConncected / onConnectionFailed / onConnectionSuspended ๋ผ๋Š” ์„ธ ๊ฐ€์ง€ ์ฝœ๋ฐฑ๋„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค. ์ด๋ฒˆ ์ด์Šˆ์˜ ๊ฒฝ์šฐ ์—ฐ๊ฒฐ ์‹œ๋„ ์ดํ›„์— ์•„๋ฌด ์ฝœ๋ฐฑ๋„ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•˜๋‹ค. ์›์ธ ๊ธฐ์กด์— Service๋ฅผ ์ƒ์†๋ฐ›๋˜ ๊ฑธ MediaBrowserService ์ƒ์†์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด์„œ onBind๋ฅผ ์žฌ์ •์˜ํ•œ ๋ถ€๋ถ„์„ ๋‚จ๊ฒจ๋‘” ๊ฒƒ์ด ์›..

[Android] java.lang.UnsupportedOperationException: This session doesn't support queue management operations

์ž‘์„ฑ์ผ: 2020.02.07 MediaControllerCompat ์žฌ์ƒ๋ชฉ๋ก ์ˆ˜์ •(addQueueItem / removeQueueItem)์„ ์‹œ๋„ํ–ˆ์„ ๋•Œ UnsupportedOperationException ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ.. java.lang.UnsupportedOperationException: This session doesn't support queue management operations ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• MediaSessionConnector์— QueueEditor๋ฅผ ์„ค์ •ํ•ด์ค€๋‹ค. queueEditor = TimelineQueueEditor(...) mediaSessionConnector.setQueueEditor(queueEditor) MediaSession์˜ ๋™์ž‘์€ ํ”Œ๋ž˜๊ทธ์— ๋”ฐ๋ผ ๊ฐ€๋Šฅํ•œ ๋™์ž‘์ธ์ง€ ์•„..

Android 10 ๋ณ€๊ฒฝ ์‚ฌํ•ญ : Scoped Storage

์ž‘์„ฑ์ผ: 20.01.21 Android 10์˜ ํฐ ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ค‘ ํ•˜๋‚˜์ธ Scoped Storage์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. (์˜ˆ์ œ ์ฝ”๋“œ๋Š” ๋ชจ๋‘ Kotlin ์ž…๋‹ˆ๋‹ค.) Scoped Storage ์‚ฌ์šฉ์ž์—๊ฒŒ ํŒŒ์ผ์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ๊ถŒํ•œ์„ ์ฃผ๊ธฐ ์œ„ํ•ด ์•ฑ ๋‚ด๋ถ€ ๋””๋ ‰ํ† ๋ฆฌ ๋ฐ ์•ฑ์—์„œ ์ƒ์„ฑํ•œ ์™ธ๋ถ€ ๋””๋ ‰ํ† ๋ฆฌ์˜ ํŒŒ์ผ ์™ธ์—๋Š” ์ ‘๊ทผ์ด ์ œํ•œ ์ ์šฉ๋˜๋Š” ๋ฒ„์ „ TargetSdkVersion ≥ 29 ๋ถ€ํ„ฐ ์ ์šฉ ์ผ์‹œ์ ์œผ๋กœ ํ•ด์ œ ๊ฐ€๋Šฅ (๊ธฐ์กด ๋ฐฉ์‹ ์‚ฌ์šฉ) ... Android 11๋ถ€ํ„ฐ๋Š” TargetSdkVersion๊ณผ ์ƒ๊ด€์—†์ด ์ ์šฉ๋  ์˜ˆ์ •์ด๋ผ๋Š” ์–˜๊ธฐ๋„ ์žˆ์Œ ๋‹ฌ๋ผ์ง€๋Š” ์  ์•ฑ ์ „์šฉ ๋””๋ ‰ํ† ๋ฆฌ Internal External ํŒŒ์ผํƒ€์ž… persist file cache file ์ผ์‹œ์ ์ธ ์บ์‹œ ํŒŒ์ผ ๊ธฐ๊ธฐ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•ด์ง€๋ฉด ์‹œ์Šคํ…œ์—์„œ ์‚ญ์ œํ•  ์ˆ˜๋„..

[Android] Dependency Injection Part 2. ์ง์ ‘ ์˜์กด์„ฑ ์ฃผ์ž…ํ•˜๊ธฐ

์ž‘์„ฑ์ผ: 2020.01.16 ์ด ๊ธ€์€ Android Developer ๊ฐ€์ด๋“œ ๋‚ด์šฉ์„ ํ† ๋Œ€๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ ์ฝ”๋“œ๋Š” Kotlin๋งŒ ๊ฐ€์ ธ์™”์œผ๋ฉฐ, Java ์ฝ”๋“œ๋Š” ์›๋ฌธ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง์ ‘ ์˜์กด์„ฑ ์ฃผ์ž…ํ•˜๊ธฐ Android์—์„œ ๊ถŒ์žฅํ•˜๋Š” ์•ฑ ์•„ํ‚คํ…์ฒ˜๋Š” ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ๋ฅผ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ž‘์€ ํด๋ž˜์Šค๋“ค๋กœ ๋”์šฑ ์ชผ๊ฐ  ํ›„, ์‹คํ–‰์„ ์œ„ํ•ด ๊ฐ ๋””ํŽœ๋˜์‹œ๋ฅผ ๋ชจ๋‘ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. MVVM ์•„ํ‚คํ…์ฒ˜๋‚˜ Repository ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, Anemic Repository๋ฅผ ๊ผญ ์ฝ์–ด๋ณด์‹œ๊ธธ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค! ํด๋ž˜์Šค ๊ฐ„์˜ ์˜์กด ๊ด€๊ณ„๋Š” ๊ทธ๋ž˜ํ”„๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๊ณ , ๊ฐ ํด๋ž˜์Šค๋Š” ์ž์‹ ์ด ์˜์กดํ•˜๋Š” ํด๋ž˜์Šค์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ํด๋ž˜์Šค์™€ ์˜์กด๊ด€๊ณ„๋ฅผ ๊ทธ๋ฆฌ๋ฉด ๊ณง ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ทธ๋ž˜ํ”„๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆผ1์—์„œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ทธ๋ž˜..

[Android] Dependency Injection Part 1. Overview

์ž‘์„ฑ์ผ: 2020.01.14 ์ด ๊ธ€์€ Android Developer ๊ฐ€์ด๋“œ ๋‚ด์šฉ์„ ํ† ๋Œ€๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ ์ฝ”๋“œ๋Š” Kotlin๋งŒ ๊ฐ€์ ธ์™”์œผ๋ฉฐ, Java ์ฝ”๋“œ๋Š” ์›๋ฌธ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜์กด์„ฑ ์ฃผ์ž…(Dependency injection, DI)์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๊ณ , Android ๊ฐœ๋ฐœ์— ์ ํ•ฉํ•œ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. DI์˜ ์›์น™์„ ๋”ฐ๋ฅด๋ฉด ์ข‹์€ ์•ฑ ์•„ํ‚คํ…์ฒ˜์˜ ๊ธฐ๋ฐ˜์„ ๊ฐ–์ถœ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. DI๋ฅผ ํ†ตํ•ด ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์žฅ์  ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋ฆฌํŒฉํ† ๋ง ์šฉ์ด ํ…Œ์ŠคํŠธ ์šฉ์ด DI์˜ ๊ธฐ๋ณธ ๊ฐœ๋… Android์—์„œ์˜ DI๋ฅผ ์‚ดํŽด๋ณด๊ธฐ ์ „์—, ์ด ํŒŒํŠธ์—์„œ๋Š” DI์˜ ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ข€ ๋” ๊ธฐ๋ณธ์ ์ธ ๊ฐœ๋…์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ ์ฃผ์ž…์ด๋ž€? ํ•œ ํด๋ž˜์Šค์—์„œ ๋‹ค๋ฅธ ํด๋ž˜์Šค ์ฐธ์กฐ๋Š” ์ž์ฃผ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Car ํด๋ž˜์Šค๋Š” Engi..