Slide 1

Slide 1 text

AndroidXͱKotlin Corou.nes @takuji31 ؼ͖ͬͯͨؔ੢ϞόΠϧΞϓϦݚڀձ

Slide 2

Slide 2 text

ࣗݾ঺հ

Slide 3

Slide 3 text

ࣗݾ঺հ • @takuji31 id:takuji31 • Takuji Nishibayashi • Hatena Co., Ltd. • App Team • ίϛοΫDAYS • δϟϯϓϧʔΩʔʂ • ΧΫϤϜ

Slide 4

Slide 4 text

ࣗݾ঺հ • Android • Kotlin • Flu-er • ! h-ps:/ /blog.takuji31.jp • " h-ps:/ /nazuna.takuji31.jp • # $ h-ps:/ /photo.takuji31.jp

Slide 5

Slide 5 text

AndroidX

Slide 6

Slide 6 text

LiveData? ViewModel? AppCompat? Naviga5on

Slide 7

Slide 7 text

࢖ͬͯ·͢ΑͶ

Slide 8

Slide 8 text

Kotlin Corou+nes

Slide 9

Slide 9 text

࢖ͬͯ·͔͢ʁ

Slide 10

Slide 10 text

Google I/O 2019

Slide 11

Slide 11 text

Android development will become increasingly Kotlin-first — h$ps://android-developers.googleblog.com/2019/05/google- io-2019-empowering-developers-to-build-experiences-on-Android- Play.html

Slide 12

Slide 12 text

AndroidXʹ΋Kotlinαϙʔτ͕ଓʑ

Slide 13

Slide 13 text

Ұ෦ → h$ps:/ /speakerdeck.com/ takuji31/androidxniqian-mubian-li- nayatura

Slide 14

Slide 14 text

ࠓ೔͸Corou%neαϙʔτͷ࿩Λ͠ ·͢

Slide 15

Slide 15 text

α൛ͷ΋ͷ΋ؚ·ΕΔͷͰ ͝ར༻͸ܭըతʹ

Slide 16

Slide 16 text

ViewModel.viewModelScope

Slide 17

Slide 17 text

ViewModelͷonClearedͰΩϟϯ ηϧ͞ΕΔCoroutineScope

Slide 18

Slide 18 text

ViewModel಺ͰCorou,neΛ࢖͍΍ ͘͢ͳΔ

Slide 19

Slide 19 text

Dispatcher͸ Dispatchers.Main͕ઃఆ͞ΕΔ

Slide 20

Slide 20 text

໌ࣔతʹࢦఆ͠ͳ͍ݶΓશͯͷॲཧ ͕ϝΠϯεϨουͰ࣮ߦ

Slide 21

Slide 21 text

class UserViewModel : ViewModel() { val name: MutableLiveData = MutableLiveData() init { viewModelScope.launch { try { val user = withContext(Dispatchers.Default) { userRepository.fetchMyUser() } name.value = user.name } catch (e: IOException) { // error handling } } } }

Slide 22

Slide 22 text

class UserViewModel : ViewModel() { val name: MutableLiveData = MutableLiveData() init { viewModelScope.launch { try { val user = withContext(Dispatchers.Default) { userRepository.fetchMyUser() } name.value = user.name } catch (e: IOException) { // error handling } } } }

Slide 23

Slide 23 text

class UserViewModel : ViewModel() { val name: MutableLiveData = MutableLiveData() init { viewModelScope.launch { try { val user = withContext(Dispatchers.Default) { userRepository.fetchMyUser() } name.value = user.name } catch (e: IOException) { // error handling } } } }

Slide 24

Slide 24 text

class UserViewModel : ViewModel() { val name: MutableLiveData = MutableLiveData() init { viewModelScope.launch { try { val user = withContext(Dispatchers.Default) { userRepository.fetchMyUser() } name.value = user.name } catch (e: IOException) { // error handling } } } }

Slide 25

Slide 25 text

class UserViewModel : ViewModel() { val name: MutableLiveData = MutableLiveData() init { viewModelScope.launch { try { val user = withContext(Dispatchers.Default) { userRepository.fetchMyUser() } name.value = user.name } catch (e: IOException) { // error handling } } } }

Slide 26

Slide 26 text

class UserViewModel : ViewModel() { val name: MutableLiveData = MutableLiveData() init { viewModelScope.launch { try { val user = withContext(Dispatchers.Default) { userRepository.fetchMyUser() } name.value = user.name } catch (e: IOException) { // error handling } } } }

Slide 27

Slide 27 text

class UserViewModel : ViewModel() { val name: MutableLiveData = MutableLiveData() init { viewModelScope.launch { try { val user = withContext(Dispatchers.Default) { userRepository.fetchMyUser() } name.value = user.name } catch (e: IOException) { // error handling } } } }

Slide 28

Slide 28 text

class UserViewModel : ViewModel() { val name: MutableLiveData = MutableLiveData() init { viewModelScope.launch { try { val user = withContext(Dispatchers.Default) { userRepository.fetchMyUser() } name.value = user.name } catch (e: IOException) { // error handling } } } }

Slide 29

Slide 29 text

class UserViewModel : ViewModel() { val name: MutableLiveData = MutableLiveData() init { viewModelScope.launch { try { val user = withContext(Dispatchers.Default) { userRepository.fetchMyUser() } name.value = user.name } catch (e: IOException) { // error handling } } } }

Slide 30

Slide 30 text

※DispatcherΛઃఆ͠ͳ͍··ॏ͍ ॲཧΛ͠ͳ͍

Slide 31

Slide 31 text

LifecycleOwner .lifecycleScope

Slide 32

Slide 32 text

Lifecycleͱ࿈ಈͨ͠ CoroutineScope

Slide 33

Slide 33 text

Lifecycle.State.DESTROYED ʹͳͬͨ࣌ʹΩϟϯηϧ͞ΕΔ CoroutineScope

Slide 34

Slide 34 text

whenCreated / whenStarted / whenResumed

Slide 35

Slide 35 text

fun onCreate(savedInstanceState: Bundle?) { lifecycleScope.launch { whenResumed { val user = withContext(Dispatchers.Default) { try { userRepository.fetchMyUser() } catch (e: IOException) { null } } if (user == null) { showErrorAndFinish() } viewModel.setup(user) } } }

Slide 36

Slide 36 text

fun onCreate(savedInstanceState: Bundle?) { lifecycleScope.launch { whenResumed { val user = withContext(Dispatchers.Default) { try { userRepository.fetchMyUser() } catch (e: IOException) { null } } if (user == null) { showErrorAndFinish() } viewModel.setup(user) } } }

Slide 37

Slide 37 text

fun onCreate(savedInstanceState: Bundle?) { lifecycleScope.launch { whenResumed { val user = withContext(Dispatchers.Default) { try { userRepository.fetchMyUser() } catch (e: IOException) { null } } if (user == null) { showErrorAndFinish() } viewModel.setup(user) } } }

Slide 38

Slide 38 text

fun onCreate(savedInstanceState: Bundle?) { lifecycleScope.launch { whenResumed { val user = withContext(Dispatchers.Default) { try { userRepository.fetchMyUser() } catch (e: IOException) { null } } if (user == null) { showErrorAndFinish() } viewModel.setup(user) } } }

Slide 39

Slide 39 text

fun onCreate(savedInstanceState: Bundle?) { lifecycleScope.launch { whenResumed { val user = withContext(Dispatchers.Default) { try { userRepository.fetchMyUser() } catch (e: IOException) { null } } if (user == null) { showErrorAndFinish() } viewModel.setup(user) } } }

Slide 40

Slide 40 text

liveData()

Slide 41

Slide 41 text

Corou%neΛLiveDataʹม׵

Slide 42

Slide 42 text

class UserViewModel : ViewModel() { val userName: LiveData = liveData { val user = userRepository.fetchMyUser() emit(user.name) } }

Slide 43

Slide 43 text

class UserViewModel : ViewModel() { val userName: LiveData = liveData { val user = userRepository.fetchMyUser() emit(user.name) } }

Slide 44

Slide 44 text

class UserViewModel : ViewModel() { val userName: LiveData = liveData { val user = userRepository.fetchMyUser() emit(user.name) } }

Slide 45

Slide 45 text

class UserViewModel : ViewModel() { val userName: LiveData = liveData { val user = userRepository.fetchMyUser() emit(user.name) } }

Slide 46

Slide 46 text

class UserViewModel : ViewModel() { val userName: LiveData = liveData { val user = userRepository.fetchMyUser() emit(user.name) } }

Slide 47

Slide 47 text

Ҿ਺ͷblock͕suspended func.on

Slide 48

Slide 48 text

LiveData͕Ac*veʹͳͬͨ࣌ʹblock ͷॲཧ͕࣮ߦ͞ΕΔ

Slide 49

Slide 49 text

ྫ֎͕ൃੜͨ͠ΒͦΕҎ߱͸஋͕ྲྀ Εͳ͍

Slide 50

Slide 50 text

ͦͷଞ

Slide 51

Slide 51 text

ͦͷଞ • CoroutineWorker • Work ManagerͷWorkerͷdoWork͕suspended func2onͳόʔδϣϯ • όοΫάϥ΢ϯυͰඇಉظॲཧΛ͍ͨ࣌͠ʹ࢖͑ͦ͏ • room-ktx • RoomͷDAOͷϝιουʹsuspended func2on͕࢖͑Δ • @Transac2onͱ஫ऍͨ͠ϝιουΛݺͿͱੜ੒͞ΕΔDAOͷϝιου ͕τϥϯβΫγϣϯͰ·ͱΊΒΕΔ

Slide 52

Slide 52 text

h"ps:/ /developer.android.com/ topic/libraries/architecture/ corou6nes

Slide 53

Slide 53 text

Enjoy Kotlin Corou.nes life!