Primeiros passos com Jetpack Glance para App Widgets

Igor Escodro
Android Dev BR
Published in
5 min readJan 26, 2022

--

Em dezembro, o Google anunciou a versão alpha da biblioteca Jetpack Glance para a criação de App Widgets. Essa nova ferramenta nos permite usar um estilo de código semelhante ao Jetpack Compose, tornando mais fácil e rápido a criação de widgets responsivos e expressivos para as nossas aplicações.

Nesse artigo irei compartilhar algumas informações importantes sobre essa nova biblioteca assim como alguns pensamentos e pontos de atenção durante a sua utilização. Por favor, tenha em vista que na época que esse artigo foi escrito a versão mais recente é a 1.0.0-alpha01, então é bem provável que algumas correções e melhorias ocorram ao longo do tempo.

Como funciona?

O Glance provê o seu próprio conjunto de Composables para serem usados no nosso GlanceAppWidget e os converte automaticamente para RemoteViews para renderizar os widgets usando as bibliotecas atuais de App Widgets.

Após uma configuração inicial semelhante a implementação padrão de widgets, tudo que precisamos fazer é implementar o nosso próprio GlanceAppWidget e GlanceAppWidgetReceiver. Segue um exemplo de um widget de “Hello World” implementado em Compose:

Glance utiliza sua própria implementação de Compose

Como mencionado anteriormente, o Glance utiliza seu próprio conjunto de Composables, o que significa que ele não é interoperável com as bibliotecas padrão do Jetpack Compose. Isso é necessário porque como o Glance precisa converter os Composables para RemoteViews, nem todo componente suporta essa transformação.

Ao implementar o seu App Widget com o Glance, preste atenção nas importações de bibliotecas. Nós precisamos implementar Column, Row, Image etc a partir de androidx.glance.* ao invés de androidx.compose.*. Se os Composables utilizados não forem da API do Glance, o seguinte erro será exibido quando o widget for adicionado à tela inicial:

Exemplo de erro do Glance App Widget

E um erro similar no Logcat:

E/GlanceAppWidget: Error in Glance App Widget
java.lang.IllegalStateException: CompositionLocal LocalDensity not present at androidx.compose.ui.platform.CompositionLocalsKt.noLocalProvidedFor(CompositionLocals.kt:170)

Nessa versão alpha alguns dos Composables e Modifiers não estão totalmente disponíveis, o que é esperado de uma versão tão nova em desenvolvimento. Então, tenha isso em mente quando começar a implementar.

Atualizar os dados é diferente do Jetpack Compose

Outro ponto que vale ressaltar ao usar essa biblioteca é que o processo de recomposição é um pouco diferente do Jetpack Compose padrão. No Compose do Glance não é possível, por exemplo, coletar um Flow de estados e fazer a tela se recompor a cada alteração.

Isso ocorre pois os mecanismos de atualização existentes no Jetpack Compose confiam no processo continuar vivo entre as atualizações de estado. Mas para a biblioteca de App Widgets, o resultado da composição (RemoteView) é enviada para o processo do launcher ao invés de continuar rodando no nosso próprio app. Caso o Glance usasse o mesmo mecanismo do Jetpack Compose para recompor a tela, ele iria consumir muita bateria.

No momento, a melhor maneira de manter os dados atualizados é manualmente chamar o método de atualização do App Widget toda vez que o dado é modificado. Por exemplo, se você possui uma lista de tarefas para ser mostrada no widget, quando o usuário adicionar uma nova tarefa então a função de update precisa ser chamada juntamente.

Para mais informações sobre esse tema, eu recomendo essa discussão esclarecedora no Issue Tracker, assim como esse pull request no incrível projeto PeopleInSpace que possui uma bela implementação para tratar essa limitação do App Widget.

As interações com usuário são mais fáceis de serem tratadas

Outra ótima adição nessa nova biblioteca é facilitar o tratamento de interações com usuário. Não há mais a necessidade de criar PendingIntent para gerenciar chamadas em processos diferentes do seu app a cada toque do usuário no widget. Agora com o Glance, você pode prover uma “action” e toda a complexidade da comunicação é feita automaticamente para nós!

No exemplo abaixo, nós setamos uma ação de actionStartActivity para abrir a HomeActivity quando o usuário apertar o botão “Home”. Simples assim!

Também é possível criar ações personalizadas para se encaixar melhor na necessidade e experiência do usuário:

Ainda é possível passar parâmetros através das ações e Activities, iniciar Services e BroadcastReceivers. Para mais informações em como tratar interações do usuário, por favor acesse a documentação oficial.

Teste no Android 12 e versões anteriores

Apesar desse ponto não se aplicar apenas quando usamos o Jetpack Glance, é uma boa ideia testar o seu App Widget em diferentes versões do Android, especialmente antes e depois do Android 12.

A mais recente versão do Android trouxe mudanças significativas e melhorias nas APIs de widget o que pode mudar o comportamento dependendo da versão. Então, se assegure que o seu layout, dimensões, prévias e ações estão funcionando bem em todas as versões!

E agora?

Os widgets são parte do ecossistema do Android desde o começo mas não receberam muito amor durante a expansão do sistema operacional. Nos últimos anos, o Google está lançando novas funcionalidades, suporte e documentações para nos ajudar a desenvolver widgets belos e responsivos em várias telas e formatos. Pessoalmente, estou muito animado com a direção que essa biblioteca está tomando, mesmo em um estágio inicial é possível ver a dedicação por trás dela.

Como sempre, eu vou compartilhar o código do Alkaa com uma abordagem mais complexa de implementação de App Widget em um cenário mais real. Esse pull request implementa um widget que mostra as tarefas mais recentes do usuário.

Alkaa Task List Widget

Também gostaria de compartilhar o vídeo oficial sobre o assunto no Android Dev Summit 2021, o “Modern Android app widgets”. O vídeo foca tanto nas alterações do Android 12 quanto nessa no Jetpack Glance.

Se você possui algum feedback referente a essa biblioteca, sinta-se livre para compartilhá-lo com o Google. Eles estão sempre abertos para ouvir nossas opiniões e nos dar suporte para criarmos uma experiência ótima para todas as pessoas desenvolvedoras. 😊

Recursos externos (em inglês)

Um agradecimento especial ao Marcel Pintó por revisar esse artigo.

Muito obrigado por ler o meu artigo! ❤️

--

--

Igor Escodro
Android Dev BR

Passionate Android developer | Google Developer Expert for Android