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

Stutern Graduate Accelerator 0.7 Android development guest session - Introduction to Multithreading and Networking on Android

Stutern Graduate Accelerator 0.7 Android development guest session - Introduction to Multithreading and Networking on Android

In this presentation, I introduced two programming concepts to beginner Android developers in the Stutern Graduate Accelerator 0.7 Android development track. I explored Multithreading and Networking on Android with RxJava and Retrofit.

I also shared some career advice based on my experience. It touched on topics such as figuring out what employers are looking out for, learning how to build a career portfolio as an Android developer and how to find job opportunities.

Moyinoluwa Adeyemi

February 18, 2020
Tweet

More Decks by Moyinoluwa Adeyemi

Other Decks in Programming

Transcript

  1. Multithreading
    and Networking
    on Android
    Moyinoluwa Adeyemi
    + career advice

    View Slide

  2. Android Google
    Developer Expert

    View Slide

  3. Multithreading
    with RxJava

    View Slide

  4. Activity/Fragment (A/F)
    Service (S)
    Content Providers (CP)
    Broadcast Receivers (BR)
    UI/Main Thread
    Android Components

    View Slide

  5. A/F
    S
    Activity/Fragment (A/F)
    Service (S)
    Content Providers (CP)
    Broadcast Receivers (BR)
    BR
    CP
    A/F
    Message Queue
    Android Components

    View Slide

  6. A/F
    S
    BR
    CP
    A/F
    }
    10ms
    }
    13ms
    }
    16ms
    }
    15ms
    }
    4ms
    60fps

    View Slide

  7. A/F
    S
    BR
    CP
    A/F
    }
    10ms
    }
    13ms
    }
    16ms
    }
    20ms
    }
    4ms
    Jank

    View Slide

  8. Common causes
    ● I/O operations (Network requests, Database Access)

    View Slide

  9. Common causes
    ● I/O operations (Network requests, Database Access)
    ● Long calculations (Image processing)

    View Slide

  10. The result
    https://developer.android.com/topic/performance/images/anr-example-framed.png

    View Slide

  11. Why bother?
    ⭐⭐⭐⭐⭐

    View Slide

  12. Why bother?
    ⭐⭐⭐⭐⭐

    View Slide

  13. Why bother?
    ⭐⭐⭐⭐⭐

    ⏱⏱⏱⏱⏱

    View Slide

  14. Solution - Android
    AsyncTask

    View Slide

  15. AsyncTask
    ● Impossible to cancel a task

    View Slide

  16. AsyncTask
    ● Impossible to cancel a task
    ● Potential memory leaks

    View Slide

  17. Solution - Kotlin
    Coroutines

    View Slide

  18. Coroutines
    ● Beyond the scope of this talk, sadly…

    View Slide

  19. Solution - Open Source library

    View Slide

  20. RxJava
    “RxJava is a Java VM implementation of ReactiveX a
    library for composing asynchronous and event-based
    programs by using observable sequences.”

    View Slide

  21. RxJava
    Subscriber Observable
    subscriber.onNext()

    View Slide

  22. RxJava - Schedulers
    “Executes arbitrary blocks of code, possibly in the future”

    View Slide

  23. RxJava - Schedulers
    “Executes arbitrary blocks of code, possibly in the future”
    Schedulers + subscribeOn()

    View Slide

  24. RxJava - Schedulers
    “Executes arbitrary blocks of code, possibly in the future”
    Schedulers + subscribeOn() + observeOn()

    View Slide

  25. Schedulers.io()
    ● Unbounded pool of threads

    View Slide

  26. Schedulers.io()
    ● Unbounded pool of threads
    ● Threads are recycled

    View Slide

  27. Schedulers.io()
    ● Unbounded pool of threads
    ● Threads are recycled
    ● Used for I/O bound tasks

    View Slide

  28. Schedulers.io()
    ● Unbounded pool of threads
    ● Threads are recycled
    ● Used for I/O bound tasks
    ● Tasks take some time to complete

    View Slide

  29. Schedulers.computation()
    ● Bounded pool of threads

    View Slide

  30. Schedulers.computation()
    ● Bounded pool of threads
    ● Used for CPU intensive tasks

    View Slide

  31. Schedulers.computation()
    ● Bounded pool of threads
    ● Used for CPU intensive tasks
    ● Computation threads limited to the number of
    CPU cores

    View Slide

  32. Schedulers.trampoline()
    ● Schedules tasks in the same thread

    View Slide

  33. Schedulers.trampoline()
    ● Schedules tasks in the same thread
    ● Blocking, but waits for the current task to finish

    View Slide

  34. subscribeOn()
    ● Determines the thread which the source
    observable emits on

    View Slide

  35. subscribeOn()
    ● Determines the thread which the source
    observable emits on
    ● Works upstream - only the first call counts

    View Slide

  36. subscribeOn()
    What thread will the source observable emit on?
    Observable.just("Hello", "World")
    .subscribeOn(Schedulers.io())
    .subscribeOn(Schedulers.computation())
    ...

    View Slide

  37. observeOn()
    ● Switches the current observable to the specified
    thread

    View Slide

  38. observeOn()
    ● Switches the current observable to the specified
    thread
    ● Works downstream - only the last call counts

    View Slide

  39. observeOn()
    What thread will the current observable be emitted on?
    Observable.just("Hello", "World")
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.computation())
    .observeOn(AndroidSchedulers.mainThread())
    ...

    View Slide

  40. TestScheduler
    “A special, non thread-safe scheduler for testing
    operators that require a scheduler without introducing
    real concurrency and allows manually advancing a
    virtual time.”

    View Slide

  41. TestScheduler - UseCase
    Observable.interval(ONE_SECOND, TimeUnit.SECONDS)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({
    .....
    })

    View Slide

  42. TestScheduler - UseCase
    private val testScheduler = TestScheduler()

    View Slide

  43. private val testScheduler = TestScheduler()
    @Before
    fun setUp() {
    RxJavaPlugins.setComputationSchedulerHandler { testScheduler }
    }
    TestScheduler - UseCase

    View Slide

  44. @Test
    fun test_shouldReturnSuccess_whenRequestIsSuccessful() {
    viewModel.result.observeForever(observer)
    testScheduler.advanceTimeBy(1, TimeUnit.SECONDS)
    verify(observer).onChanged(...)
    }
    TestScheduler - UseCase

    View Slide

  45. AndroidSchedulers.mainThread()
    ● Available only in RxAndroid

    View Slide

  46. AndroidSchedulers.mainThread()
    ● Available only in RxAndroid
    ● Performs Android UI based work on the main thread

    View Slide

  47. Import RxJava in Gradle
    implementation "io.reactivex.rxjava2:rxjava:$rx_java2_version"
    implementation "io.reactivex.rxjava2:rxandroid:$rx_android_version"

    View Slide

  48. Networking with
    Retrofit

    View Slide

  49. Retrofit
    ● Open source library for making HTTP requests

    View Slide

  50. Retrofit
    ● Open source library for making HTTP requests
    ● Accepts an HTTP client

    View Slide

  51. Retrofit
    ● Open source library for making HTTP requests
    ● Accepts an HTTP client
    ● Accepts a Call Adapter factory

    View Slide

  52. Retrofit
    ● Open source library for making HTTP requests
    ● Accepts an HTTP client
    ● Accepts a Call Adapter factory
    ● Accepts a Converter factory

    View Slide

  53. Retrofit - Converters
    ● Gson: com.squareup.retrofit2:converter-gson
    ● Jackson: com.squareup.retrofit2:converter-jackson
    ● Moshi: com.squareup.retrofit2:converter-moshi
    ● Protobuf: com.squareup.retrofit2:converter-protobuf
    ● Wire: com.squareup.retrofit2:converter-wire
    ● Simple XML: com.squareup.retrofit2:converter-simplexml
    ● Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars

    View Slide

  54. Retrofit + OkHttp
    val okHttpClient = OkHttpClient.Builder()
    .build()

    View Slide

  55. Retrofit + OkHttp
    Retrofit.Builder()
    .client(okHttpClient)

    View Slide

  56. Retrofit
    Retrofit.Builder()
    .client(okHttpClient)
    .baseUrl(BuildConfig.BASE_URL)

    View Slide

  57. Retrofit
    Retrofit.Builder()
    .client(okHttpClient)
    .baseUrl(BuildConfig.BASE_URL)
    .addConverterFactory(MoshiConverterFactory.create(moshi))

    View Slide

  58. Retrofit
    Retrofit.Builder()
    .client(okHttpClient)
    .baseUrl(BuildConfig.BASE_URL)
    .addConverterFactory(MoshiConverterFactory.create(moshi))
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .build()

    View Slide

  59. Retrofit - Annotations
    GET
    POST
    PUT
    DELETE
    HEAD

    View Slide

  60. Retrofit - Interface
    https://demo.sga.org/latest?town=lagos
    interface DemoService {
    @GET("/latest")
    fun getLatestDemo(@Query("town") town: String): Observable
    }

    View Slide

  61. Retrofit - Interface
    https://demo.sga.org/latest?town=lagos
    interface DemoService {
    @GET("/latest")
    fun getLatestDemo(@Query("town") town: String): Observable
    }
    val demoService = retrofit.create(DemoService::class.java)

    View Slide

  62. Retrofit + RxJava (Multithreading)
    https://demo.sga.org/latest?town=lagos
    demoService.getLatestDemo("lagos")
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())

    View Slide

  63. Retrofit + RxJava (Error handling)
    https://demo.sga.org/latest?town=lagos
    demoService.getLatestDemo("lagos")
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ demo -> ...},
    { error -> ... })

    View Slide

  64. Import Retrofit in Gradle
    // moshi
    implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"
    implementation "com.squareup.moshi:moshi-adapters:$moshi_version"
    // Retrofit
    implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
    implementation "com.squareup.retrofit2:converter-moshi:$moshi_converter_version"
    implementation "com.squareup.retrofit2:adapter-rxjava2:$rx_java_adapter_version"

    View Slide

  65. Career Section

    View Slide

  66. What are employers
    looking for?

    View Slide

  67. What are employers looking for?
    ● Technical Experience suitable for the role

    View Slide

  68. What are employers looking for?
    ● Technical Experience suitable for the role
    ● “Soft” skills

    View Slide

  69. What are employers looking for?
    ● Technical Experience suitable for the role
    ● “Soft” skills
    ● Growth potential

    View Slide

  70. What are employers looking for?
    ● Technical Experience suitable for the role
    ● “Soft” skills
    ● Growth potential
    ● Bonus - Writing skills

    View Slide

  71. What are employers looking for?
    ● Technical Experience suitable for the role
    ● “Soft” skills
    ● Growth potential
    ● Bonus - Writing skills
    ● Bonus - Contributions to the community

    View Slide

  72. Building a career
    portfolio

    View Slide

  73. Building a career portfolio
    ● Contribute to an existing project

    View Slide

  74. Building a career portfolio
    ● Contribute to an existing project
    ● Upload code snippets or sample apps to Github

    View Slide

  75. Building a career portfolio
    ● Contribute to an existing project
    ● Upload code snippets or sample apps to Github
    ● Publish apps on Google Play

    View Slide

  76. Building a career portfolio
    ● Contribute to an existing project
    ● Upload code snippets or sample apps to Github
    ● Publish apps on Google Play
    ● Write technical articles

    View Slide

  77. Building a career portfolio
    ● Contribute to an existing project
    ● Upload code snippets or sample apps to Github
    ● Publish apps on Google Play
    ● Write technical articles
    ● Give talks

    View Slide

  78. How to find
    opportunities

    View Slide

  79. How to find opportunities
    ● Social media (LinkedIn, Twitter, StackOverflow Jobs)

    View Slide

  80. How to find opportunities
    ● Social media (LinkedIn, Twitter, StackOverflow Jobs)
    ● Newsletters (Forloop, Android/Kotlin Weekly)

    View Slide

  81. How to find opportunities
    ● Social media (LinkedIn, Twitter, StackOverflow Jobs)
    ● Newsletters (Forloop, Android/Kotlin Weekly)
    ● Job Search marketplace (Hired.com, Fiverr, Upwork)

    View Slide

  82. How to find opportunities
    ● Social media (LinkedIn, Twitter, StackOverflow Jobs)
    ● Newsletters (Forloop, Android/Kotlin Weekly)
    ● Job Search marketplace (Hired.com, Fiverr, Upwork)
    ● Company Career pages

    View Slide

  83. How to find opportunities
    ● Social media (LinkedIn, Twitter, StackOverflow Jobs)
    ● Newsletters (Forloop, Android/Kotlin Weekly)
    ● Job Search marketplace (Hired.com, Fiverr, Upwork)
    ● Company Career pages
    ● Employee referrals

    View Slide

  84. Questions?

    View Slide

  85. Resources
    ● https://developer.android.com/training/articles/perf-anr
    ● http://hvasconcelos.github.io/articles/Offloading-work-from-the-
    UI-Thread
    ● https://blog.gojekengineering.com/multi-threading-like-a-boss-in
    -android-with-rxjava-2-b8b7cf6eb5e2
    ● https://square.github.io/retrofit/
    ● Reactive Programming with RxJava - Tomasz Nurkiewicz

    View Slide

  86. Take home task

    View Slide

  87. Take home task
    Create a one page app with GitHub’s public REST API,
    listing all names of users in Lagos.
    The app should make use of both RxJava and Retrofit for
    networking. Make the network request on the io thread.
    For bonus points, use an Android App architecture and
    write tests.

    View Slide

  88. Thank you!

    View Slide