$30 off During Our Annual Pro Sale. View Details »

AndroidXとKotlin Coroutines

AndroidXとKotlin Coroutines

Takuji Nishibayashi

May 15, 2019
Tweet

More Decks by Takuji Nishibayashi

Other Decks in Technology

Transcript

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

    View Slide

  2. ࣗݾ঺հ

    View Slide

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

    View Slide

  4. ࣗݾ঺հ
    • Android
    • Kotlin
    • Flu-er

    !
    h-ps:/
    /blog.takuji31.jp

    "
    h-ps:/
    /nazuna.takuji31.jp

    # $
    h-ps:/
    /photo.takuji31.jp

    View Slide

  5. AndroidX

    View Slide

  6. LiveData?
    ViewModel?
    AppCompat?
    Naviga5on

    View Slide

  7. ࢖ͬͯ·͢ΑͶ

    View Slide

  8. Kotlin Corou+nes

    View Slide

  9. ࢖ͬͯ·͔͢ʁ

    View Slide

  10. Google I/O 2019

    View Slide

  11. 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

    View Slide

  12. AndroidXʹ΋Kotlinαϙʔτ͕ଓʑ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  16. ViewModel.viewModelScope

    View Slide

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

    View Slide

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

    View Slide

  19. Dispatcher͸
    Dispatchers.Main͕ઃఆ͞ΕΔ

    View Slide

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

    View Slide

  21. 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
    }
    }
    }
    }

    View Slide

  22. 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
    }
    }
    }
    }

    View Slide

  23. 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
    }
    }
    }
    }

    View Slide

  24. 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
    }
    }
    }
    }

    View Slide

  25. 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
    }
    }
    }
    }

    View Slide

  26. 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
    }
    }
    }
    }

    View Slide

  27. 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
    }
    }
    }
    }

    View Slide

  28. 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
    }
    }
    }
    }

    View Slide

  29. 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
    }
    }
    }
    }

    View Slide

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

    View Slide

  31. LifecycleOwner
    .lifecycleScope

    View Slide

  32. Lifecycleͱ࿈ಈͨ͠
    CoroutineScope

    View Slide

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

    View Slide

  34. whenCreated / whenStarted /
    whenResumed

    View Slide

  35. 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)
    }
    }
    }

    View Slide

  36. 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)
    }
    }
    }

    View Slide

  37. 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)
    }
    }
    }

    View Slide

  38. 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)
    }
    }
    }

    View Slide

  39. 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)
    }
    }
    }

    View Slide

  40. liveData()

    View Slide

  41. Corou%neΛLiveDataʹม׵

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  47. Ҿ਺ͷblock͕suspended func.on

    View Slide

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

    View Slide

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

    View Slide

  50. ͦͷଞ

    View Slide

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

    View Slide

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

    View Slide

  53. Enjoy Kotlin Corou.nes life!

    View Slide