Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ao infinito e além! Novidades do Jetpack para profissionais Android.

Ao infinito e além! Novidades do Jetpack para profissionais Android.

This talk was held during DevCamp 2019, that happened on August 16th, in Campinas, São Paulo, Brazil.

I gave a 40min talk about what's new on the Android Jetpack APIs and libraries, how can we benefit ourselves using these latest new resources and what's the future of Jetpack for Android developers.

The content is in pt-BR.

More info: https://www.devcamp.com.br/edicoes-anteriores/devcamp-2019/

Walmyr Carvalho

August 16, 2019
Tweet

More Decks by Walmyr Carvalho

Other Decks in Technology

Transcript

  1. Ao infinito e além!
    Novidades do Jetpack para
    profissionais Android. ✨
    Walmyr Carvalho
    Founder @ Kusudama, Mobile Technical Leader @ idwall
    Google Developer Expert, Android
    @walmyrcarvalho

    View full-size slide

  2. Bom dia, DevCamp!
    Meu nome é Walmyr Carvalho,
    muito prazer! :)

    View full-size slide

  3. Trabalho com desenvolvimento Android há 9
    anos e sou um Google Developer Experts de
    Android no Brasil há 3 anos.
    Além disso, estou muito próximo da
    comunidade nacional de Android, sendo
    organizador do GDG São Paulo, Kotlin Meetup
    São Paulo e Android Dev BR, a maior
    comunidade brasileira de Android do mundo,
    com mais de 5700 pessoas!


    Também apoio o empreendedorismo nacional,
    sendo mentor de Android e mobile no Google
    Developers Launchpad Accelerator e na ACE
    Startups.

    View full-size slide

  4. Já ajudei a evoluir produtos mobile
    para empresas como Loggi, 99, Cielo,
    CI&T, Hotel Urbano e Globo Esporte,
    durante mais de 9 anos de carreira
    como especialista em Android.
    Fonte: Google Play

    View full-size slide

  5. Nesse ano fundei a Kusudama,
    um estúdio de desenvolvimento e
    design de produtos digitais para
    Android e iOS, que tem como seu
    objetivo criar experiências que
    tratem seus usuários com respeito
    dentro do universo mobile.

    View full-size slide

  6. Recentemente me juntei ao
    grande time da idwall como
    Mobile Technical Leader, com o
    objetivo de criar a próxima
    plataforma de identidade digital
    brasileira no mobile, além de
    soluções para empresas que
    buscam aumentar a confiança na
    identificação dos seus usuários.

    View full-size slide

  7. Um ano de Android Jetpack!
    Como foi a trajetória do projeto até agora?

    View full-size slide

  8. Pergunta:
    Quem aí já usa alguma coisa do Jetpack nos
    próprios projetos para Android?

    View full-size slide

  9. Fonte: Android Developers

    View full-size slide

  10. O Android Jetpack é um conjunto de ferramentas,
    bibliotecas e boas práticas criado pelo Google, com o
    objetivo de ajudar profissionais Android a criarem
    aplicações com maior qualidade!

    View full-size slide

  11. Android KTX
    AppCompat
    Auto
    Benchmark
    Multidex
    Security
    Test
    TV
    Wear OS by Google
    Data Binding
    Lifecycles
    LiveData
    Navigation
    Paging
    Room
    ViewModel
    WorkManager
    CameraX
    Download Manager
    Media & Playback
    Notifications
    Multidex
    Permissions
    Preferences
    Sharing
    Slices
    Animation & transitions
    Emoji
    Fragment
    Layout
    Palette
    ViewPager2
    Compose
    ConstraintLayout 2.0
    Biometrics

    View full-size slide

  12. Android KTX
    AppCompat
    Auto
    Benchmark
    Multidex
    Security
    Test
    TV
    Wear OS by Google
    Data Binding
    Lifecycles
    LiveData
    Navigation
    Paging
    Room
    ViewModel
    WorkManager
    CameraX
    Download Manager
    Media & Playback
    Notifications
    Multidex
    Permissions
    Preferences
    Sharing
    Slices
    Animation & transitions
    Emoji
    Fragment
    Layout
    Palette
    ViewPager2
    Compose
    Base Arquitetura Comportamento UI
    ConstraintLayout 2.0
    Biometrics

    View full-size slide

  13. Android KTX
    AppCompat
    Auto
    Benchmark
    Multidex
    Security
    Test
    TV
    Wear OS by Google
    Data Binding
    Lifecycles
    LiveData
    Navigation
    Paging
    Room
    ViewModel
    WorkManager
    CameraX
    Download Manager
    Media & Playback
    Notifications
    Multidex
    Permissions
    Preferences
    Sharing
    Slices
    Animation & transitions
    Emoji
    Fragment
    Layout
    Palette
    ViewPager2
    Compose
    Base Arquitetura Comportamento UI
    AndroidX
    ConstraintLayout 2.0
    Biometrics

    View full-size slide

  14. O Jetpack foi anunciado há 1 ano lá no Google I/O ’18,
    e desde então o Google vem trabalhado em uma série
    de boas novidades para esse conjunto, sempre
    trabalhando bem próximo de empresas e da
    comunidade. ❤✨

    View full-size slide

  15. Fonte: Android Developers (YouTube)

    View full-size slide

  16. De acordo com o Google, 80% dos top 1.000 apps
    no Google Play já estão usando Jetpack, o que é um
    número bem impressionante e mostra o impacto do
    projeto na comunidade Android em geral!
    Fonte: bit.do/whats-new-jetpack

    View full-size slide

  17. Fonte: Android Developers, 2019

    View full-size slide

  18. Infelizmente hoje não vou conseguir me aprofundar
    sobre todas as bibliotecas e APIs que o Jetpack tem,
    pois é muito conteúdo para pouco tempo! 

    Mas já existe uma série de materiais legais sobre o
    assunto, principalmente por parte do Google!

    View full-size slide

  19. Android Jetpack - Site
    Documentação oficial e mais
    detalhes sobre o Jetpack
    developers.android.com/jetpack

    View full-size slide

  20. Android Jetpack - YouTube
    Lista de vídeos com vários talks
    sobre as APIs do Jetpack
    bit.do/android-jetpack-youtube

    View full-size slide

  21. Bacana! E o que temos de novidades no
    Jetpack desde o seu lançamento?

    View full-size slide

  22. Novidades do Android Jetpack!
    O que temos de legal?

    View full-size slide

  23. Vamos dar uma olhada naquela lista de APIs e
    bibliotecas novamente?

    View full-size slide

  24. Android KTX
    AppCompat
    Auto
    Benchmark
    Multidex
    Security
    Test
    TV
    Wear OS by Google
    Data Binding
    Lifecycles
    LiveData
    Navigation
    Paging
    Room
    ViewModel
    WorkManager
    CameraX
    Download Manager
    Media & Playback
    Notifications
    Multidex
    Permissions
    Preferences
    Sharing
    Slices
    Animation & transitions
    Emoji
    Fragment
    Layout
    Palette
    ViewPager2
    Compose
    Base Arquitetura Comportamento UI
    AndroidX
    ConstraintLayout 2.0
    Biometrics

    View full-size slide

  25. Android KTX
    AppCompat
    Auto ⚠
    Benchmark ⚠
    Multidex
    Security ⚠
    Test
    TV
    Wear OS by Google
    Data Binding
    Lifecycles ⚠
    LiveData ⚠
    Navigation ✅
    Paging
    Room
    ViewModel ⚠
    WorkManager ✅
    CameraX ⚠
    Download Manager
    Media & Playback
    Notifications
    Multidex
    Permissions
    Preferences
    Sharing
    Slices
    Animation & transitions
    Emoji
    Fragment
    Layout
    Palette
    ViewPager2 ⚠
    Compose ⚠
    Base Arquitetura Comportamento UI
    AndroidX
    ConstraintLayout 2.0 ⚠
    Biometrics ⚠

    View full-size slide

  26. Bastante coisa nova! Vale lembrar que grande parte
    das novidades ainda se encontra em estágios de
    desenvolvimento alpha e beta! ⚠


    Vamos dar uma olhada:

    View full-size slide

  27. LiveData e Lifecycles + Coroutines (alpha) ⚠
    class MyViewModel: ViewModel() {
    init {
    viewModelScope.launch {
    // Coroutine that will be canceled
    // when the ViewModel is cleared.
    }
    }
    }

    View full-size slide

  28. LiveData e Lifecycles + Coroutines (alpha) ⚠
    class MyFragment: Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    viewLifecycleOwner.lifecycleScope.launch {
    val params = TextViewCompat.getTextMetricsParams(textView)
    val precomputedText = withContext(Dispatchers.Default) {
    PrecomputedTextCompat.create(longTextContent, params)
    }
    TextViewCompat.setPrecomputedText(textView, precomputedText)
    }
    }
    }

    View full-size slide

  29. LiveData e Lifecycles + Coroutines (alpha) ⚠
    val user: LiveData = liveData {
    val data = database.loadUser() // loadUser is a suspend function.
    emit(data)
    }

    View full-size slide

  30. LiveData e Lifecycles + Coroutines (alpha) ⚠
    val user: LiveData = liveData {
    emit(Result.loading())
    try {
    emit(Result.success(fetchUser())
    } catch(ioException: Exception) {
    emit(Result.error(ioException))
    }
    }

    View full-size slide

  31. LiveData e Lifecycles + Coroutines (alpha) ⚠
    class MyViewModel: ViewModel() {
    private val userId: LiveData = MutableLiveData()
    val user = userId.switchMap { id ->
    liveData(context = viewModelScope.coroutineContext + Dispatchers.IO) {
    emit(database.loadUserById(id))
    }
    }
    }

    View full-size slide

  32. LiveData e Lifecycles + Coroutines (alpha) ⚠
    class UserDao: Dao {
    @Query("SELECT * FROM User WHERE id = :id")
    fun getUser(id: String): LiveData
    }
    class MyRepository {
    fun getUser(id: String) = liveData {
    val disposable = emitSource(
    userDao.getUser(id).map {
    Result.loading(it)
    }
    )
    // Fetch user, save, etc
    }
    }

    View full-size slide

  33. dependencies {
    androidTestImplementation "androidx.benchmark:benchmark-junit4:1.0.0-alpha04"
    }
    Benchmark (alpha) ⚠ module/build.gradle

    View full-size slide


  34. android:debuggable="false"
    tools:ignore="HardcodedDebugMode"
    tools:replace="android:debuggable"/>
    Benchmark (alpha) ⚠ module/src/androidTest/AndroidManifest.xml

    View full-size slide

  35. @RunWith(AndroidJUnit4::class)
    class MyBenchmark {
    @get:Rule
    val benchmarkRule = BenchmarkRule()
    @Test
    fun benchmarkSomeWork() = benchmarkRule.measureRepeated {
    doSomeWork()
    }
    }
    Benchmark (alpha) ⚠ module/src/androidTest/java//MyBenchmark.kt

    View full-size slide

  36. // Optional, but highly recommended values
    val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
    val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)
    Security (alpha) ⚠

    View full-size slide

  37. val fileToRead = "my_sensitive_data.txt"
    lateinit var byteStream: ByteArrayOutputStream
    val encryptedFile = EncryptedFile.Builder(
    File(context.getFilesDir(), fileToRead),
    context,
    masterKeyAlias,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
    ).build()
    Security (alpha) ⚠

    View full-size slide

  38. try {
    encryptedFile.openFileInput().use { fileInputStream ->
    try {
    byteStream = ByteArrayOutputStream()
    var nextByte = fileInputStream.read()
    while (nextByte != -1) {
    byteStream.write(nextByte)
    nextByte = fileInputStream.read()
    }
    val fileContents = byteStream.toByteArray()
    } catch (ex: Exception) {
    // Error occurred opening raw file for reading.
    } finally {
    fileInputStream.close()
    }
    })
    } catch (ex: IOException) {
    // Error occurred opening encrypted file for reading.
    }
    Security (alpha) ⚠

    View full-size slide

  39. val fileToWrite = "my_other_sensitive_data.txt"
    val encryptedFile = EncryptedFile.Builder(
    File(context.getFilesDir(), fileToWrite),
    context,
    masterKeyAlias,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
    ).build()
    // Write to a file.
    try {
    val outputStream: FileOutputStream? = encryptedFile.openFileOutput()
    outputStream?.apply {
    write("MY SUPER SECRET INFORMATION"
    .toByteArray(Charset.forName("UTF-8")))
    flush()
    close()
    }
    } catch (exception: IOException) {
    // Error occurred opening file for writing.
    }
    Security (alpha) ⚠

    View full-size slide

  40. val sharedPreferences = EncryptedSharedPreferences
    .create(
    fileName,
    masterKeyAlias,
    context,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )
    val sharedPrefsEditor = sharedPreferences.edit()
    Security (alpha) ⚠

    View full-size slide

  41. // Setup a SavedStateHandle on a ViewModel
    val vm = ViewModelProvider(this, SavedStateVMFactory(this))
    .get(SavedStateViewModel::class.java)
    // Adding the SavedStateHandle on ViewModel constructor
    class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel()
    {
    ...
    }
    ViewModel com SavedState (alpha) ⚠

    View full-size slide

  42. // A classe SavedStateHandle tem métodos helpers
    // que ajudam a lidar com o map de chave-valor:
    //
    // - get(String key)
    // - contains(String key)
    // - remove(String key)
    // - set(String key, T value)
    // - keys()
    ViewModel com SavedState (alpha) ⚠

    View full-size slide

  43. Biometrics (beta) ⚠

    View full-size slide

  44. dependencies {
    implementation 'androidx.biometric:biometric:1.0.0-alpha04'
    }
    Biometrics (alpha) ⚠ module/build.gradle

    View full-size slide

  45. private val executor = Executor { }
    override fun onCreate(savedInstanceState: Bundle?) {
    // Prompt appears when user clicks "Log in"
    val biometricLoginButton = findViewById(R.id.biometric_login)
    biometricLoginButton.setOnClickListener { showBiometricPrompt() }
    }
    Biometrics (alpha) ⚠

    View full-size slide

  46. val promptInfo = BiometricPrompt.PromptInfo.Builder()
    .setTitle("Biometric login for my app")
    .setSubtitle("Log in using your biometric credential")
    .setNegativeButtonText("Cancel")
    .build()
    Biometrics (alpha) ⚠

    View full-size slide

  47. val biometricPrompt = BiometricPrompt(this, executor,
    object : BiometricPrompt.AuthenticationCallback() {

    override fun onAuthenticationError(errorCode: Int, errorMessage: CharSequence) {
    super.onAuthenticationError(errorCode, errorMessage)

    Toast.makeText(context,
    "Authentication error: $errorMessage", Toast.LENGTH_SHORT)
    .show()
    }


    Biometrics (alpha) ⚠

    View full-size slide


  48. override fun onAuthenticationSucceeded(result:BiometricPrompt.AuthenticationResult) {
    super.onAuthenticationSucceeded(result)
    val authenticatedCryptoObject: BiometricPrompt.CryptoObject = result.getCryptoObject()
    }
    override fun onAuthenticationFailed() {
    super.onAuthenticationFailed()

    Toast.makeText(context, "Authentication failed”, Toast.LENGTH_SHORT).show()
    }
    biometricPrompt.authenticate(promptInfo)
    Biometrics (alpha) ⚠

    View full-size slide

  49. Bônus demo: Jetpack Compose
    Criando UIs de forma declarativa! ⚠

    View full-size slide

  50. Se eu quiser aprender mais,
    onde eu posso encontrar material?

    View full-size slide

  51. Android Jetpack - Site
    Documentação oficial e mais
    detalhes sobre o Jetpack
    developers.android.com/jetpack

    View full-size slide

  52. Android Jetpack - YouTube
    Lista de vídeos com vários talks
    sobre as APIs do Jetpack
    bit.do/android-jetpack-youtube

    View full-size slide

  53. Android Dev BR
    Maior comunidade lusófona de Android no
    Slack, com quase de 6.000 membros! /❤✨
    slack.androiddevbr.org

    View full-size slide

  54. Perguntas?
    Ficou alguma dúvida?

    View full-size slide

  55. Muito obrigado!
    Se tiver qualquer dúvida ou sugestão,
    pode falar comigo. ❤
    @walmyrcarvalho
    /walmyrcarvalho
    [email protected]

    View full-size slide