Introdução

Este tutorial é uma abordagem passo a passo para o desenvolvimento de aplicações Android modernas utilizando Kotlin. Vamos explorar o Ktor, uma biblioteca assíncrona e leve para comunicação com servidores via APIs, juntamente com o Jetpack Compose, a nova forma declarativa de criar interfaces de usuário no Android. Aprenderemos sobre a configuração do ambiente, a criação de uma API simples com Ktor e a implementação de uma interface de usuário responsiva e moderna usando o Jetpack Compose. Este guia é ideal tanto para iniciantes quanto para aqueles que desejam expandir seus conhecimentos em desenvolvimento Android com as tecnologias mais recentes.

Etapas

  1. Configuração do Ambiente de Desenvolvimento

    Antes de começar, certifique-se de ter o Android Studio instalado na sua máquina. Você pode baixá-lo em https://developer.android.com/studio. Após instalar, crie um novo projeto no Android Studio com `Empty Compose Activity`, escolhendo `Kotlin` como a linguagem. Além disso, você deve configurar o Ktor em seu projeto, que será utilizado para realizar chamadas a APIs.

    build.gradle (app)
    dependencies {
        implementation 'io.ktor:ktor-client-core:2.2.2'
        implementation 'io.ktor:ktor-client-cio:2.2.2'
        implementation 'io.ktor:ktor-client-serialization:2.2.2'
        implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0'
        // Jetpack Compose dependencies
        implementation 'androidx.compose.ui:ui:1.3.0'
        implementation 'androidx.compose.material:material:1.3.0'
        implementation 'androidx.compose.ui:ui-tooling-preview:1.3.0'
        implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
        implementation 'androidx.activity:activity-compose:1.6.1'
    }

  2. Criando uma API com Ktor

    Vamos configurar uma API simples utilizando Ktor. Crie uma nova classe Kotlin chamada `Api.kt`. Nesta classe, vamos definir algumas rotas simples que retornarão dados em formato JSON.

    Api.kt
    import io.ktor.http.*
    import io.ktor.application.*
    import io.ktor.response.*
    import io.ktor.routing.*
    import io.ktor.features.ContentNegotiation
    import io.ktor.serialization.*
    
    fun Application.module() {
        install(ContentNegotiation) {
            json()
        }
    
        routing {
            get("/users") {
                call.respond(HttpStatusCode.OK, listOf(User(1, "Alice"), User(2, "Bob")))
            }
        }
    }
    
    data class User(val id: Int, val name: String)

  3. Configurando o Cliente Ktor

    Agora que temos uma API simples, precisamos configurar o cliente Ktor para fazer chamadas a essa API. Crie uma classe de repositório `UserRepository.kt` que será responsável por interagir com a API.

    UserRepository.kt
    import io.ktor.client.*
    import io.ktor.client.request.*
    import io.ktor.client.features.json.*
    import io.ktor.client.features.json.serializer.*
    
    class UserRepository {
        private val client = HttpClient { 
            install(JsonFeature) { 
                serializer = KotlinxSerializer() 
            }
        }
    
        suspend fun getUsers(): List<User> {
            return client.get("http://localhost:8080/users")
        }
    }

  4. Construindo a Interface com Jetpack Compose

    Com o cliente configurado, vamos construir uma interface simples usando o Jetpack Compose para exibir os usuários que recebemos da API. Crie uma nova função de Composable chamada `UserList`. Esta função irá usar o objeto `UserRepository` para buscar e exibir os usuários na tela.

    UserList.kt
    import androidx.compose.foundation.layout.*
    import androidx.compose.material.*
    import androidx.compose.runtime.*
    import androidx.compose.ui.Alignment
    import androidx.compose.ui.Modifier
    import androidx.compose.ui.unit.dp
    
    @Composable
    fun UserList(userRepository: UserRepository) {
        var users by remember { mutableStateOf(emptyList<User>()) }
        var loading by remember { mutableStateOf(true) }
    
        LaunchedEffect(Unit) {
            users = userRepository.getUsers()
            loading = false
        }
    
        if (loading) {
            CircularProgressIndicator() 
        } else {
            LazyColumn { 
                items(users) { user ->
                    Text(text = user.name, modifier = Modifier.padding(8.dp))
                }
            }
        }
    }

  5. Implementando o Composable Principal

    Agora, vamos implementar o `MainActivity.kt`, que será a porta de entrada da nossa aplicação. Aqui, chamaremos o `UserList` dentro do `setContent` após a definição do `onCreate`.

    MainActivity.kt
    import android.os.Bundle
    import androidx.activity.ComponentActivity
    import androidx.activity.compose.setContent
    import androidx.compose.material.MaterialTheme
    import androidx.compose.material.Surface
    import androidx.compose.ui.tooling.preview.Preview
    
    class MainActivity : ComponentActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val repository = UserRepository()
            setContent { 
                MaterialTheme {
                    Surface {
                        UserList(repository)
                    }
                }
            }
        }
    @Preview
    @Composable
    fun DefaultPreview() {
        MaterialTheme {
            UserList(UserRepository())
        }
    } 
    }

  6. Testando a Aplicação

    Com todas as partes em funcionamento, compile e execute sua aplicação no Android Studio em um emulador ou dispositivo real. Certifique-se de que a API Ktor esteja em execução no servidor local para que a aplicação consiga fazer as chamadas corretas.

    commands
    # Compilar e executar a aplicação
    Run > 'Run app'

  7. Adicionando Testes a sua Aplicação

    Por fim, vamos adicionar alguns testes unitários para garantir que a aplicação funcione conforme o esperado. Crie uma classe de teste `UserRepositoryTest` para verificar a lógica de obtenção de usuários.

    UserRepositoryTest.kt
    import io.ktor.client.mock.*
    import io.ktor.client.request.get
    import io.ktor.http.*
    import io.ktor.mock.MockEngine
    import io.kotest.core.spec.style.StringSpec
    import io.kotest.matchers.shouldBe
    
    class UserRepositoryTest : StringSpec({
        "should return list of users" { 
            val engine = MockEngine { request -> 
                respond("[{'id':1, 'name':'Alice'},{'id':2, 'name':'Bob'}]", HttpStatusCode.OK)
            }
    
            val repository = UserRepository(engine)
            val users = repository.getUsers()
    
            users.size shouldBe 2
        }
    })

Conclusão

Neste tutorial, você aprendeu como desenvolver aplicações Android utilizando Kotlin, Ktor e Jetpack Compose. Desde a configuração do ambiente até a construção da API e da interface de usuário, cobrimos cada passo do processo. Agora, você está equipado para criar aplicações modernas e responsivas no Android. Ao integrar Ktor, você pode facilmente comunicar-se com APIs, tornando seu aplicativo mais dinâmico e funcional. Continue explorando mais sobre essa stack tecnológica para desbloquear ainda mais o potencial do desenvolvimento Android.

Hashtags

#Android #Kotlin #Ktor #JetpackCompose #DesenvolvimentoDeSoftware #API