O modo de rejeição avançada está disponível no compilador do Compose. Quando ativado, ele muda o comportamento do compilador de duas maneiras:
- Os elementos combináveis com parâmetros instáveis podem ser pulados.
- As lambdas com capturas instáveis são gravadas
Ativar o modo de rejeição avançada
Para ativar o salto forte para um módulo do Gradle em uma versão anterior,
inclua a seguinte opção no
bloco composeCompiler
da configuração do Gradle:
android { ... }
composeCompiler {
enableStrongSkippingMode = true
}
Recurso combinável para pular
O modo de pular forte relaxa algumas das regras de estabilidade normalmente aplicadas pelo compilador do Compose quando se trata de pular e de funções combináveis. Por padrão, o compilador do Compose marcará uma função combinável como pulável se todos os argumentos tiverem valores estáveis. O modo de rejeição avançada muda isso.
Com a omissão forte ativada, todas as funções combináveis reiniciáveis se tornam omitíveis. Isso acontece com parâmetros instáveis ou não. As funções combináveis não reiniciáveis não podem ser puladas.
Quando pular
Para determinar se um elemento combinável será ignorado durante a recomposição, o Compose compara o valor de cada parâmetro com os valores anteriores. O tipo de comparação depende da estabilidade do parâmetro.
- Os parâmetros instáveis são comparados usando a igualdade de instância (
===
) - Os parâmetros estáveis são comparados usando a igualdade de objetos (
Object.equals()
).
Se todos os parâmetros atenderem a esses requisitos, o Compose vai pular o elemento combinável durante a recomposição.
Você pode querer que um elemento combinável desative a opção "Pular forte". Ou seja,
talvez você queira um elemento combinável reinicializável, mas não pulável. Nesse caso, use a
anotação @NonSkippableComposable
.
@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}
Anotar classes como estáveis
Se você quiser que um objeto use a igualdade de objeto em vez da igualdade de instância,
continue a anotar a classe especificada com @Stable
.
Um exemplo de quando você pode
precisar fazer isso é ao observar uma lista inteira de objetos. As fontes de dados, como
o Room, vão alocar novos objetos para cada item da lista sempre que um deles
mudar.
Memorização Lambda
O modo de pular forte também permite mais memoização de lambdas dentro dos elementos combináveis. Com a rejeição avançada ativada, cada lambda dentro de uma função combinável é lembrada automaticamente.
Exemplos
Para conseguir a memorização de lambdas dentro de elementos combináveis ao usar a ação de pular forte,
o compilador envolve a lambda com uma chamada remember
. Ela é codificada com as
capturas da lambda.
Considere um caso em que você tem uma lambda como no exemplo abaixo:
@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
val lambda = {
use(unstableObject)
use(stableObject)
}
}
Com o salto forte ativado, o compilador memoriza a lambda ao envolvê-la em
uma chamada remember
:
@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
val lambda = remember(unstableObject, stableObject) {
{
use(unstableObject)
use(stableObject)
}
}
}
As chaves seguem as mesmas regras de comparação que as funções combináveis. O ambiente de execução compara chaves instáveis usando a igualdade de instâncias. Ela compara chaves estáveis usando a igualdade de objetos.
Memoização e recomposição
Essa otimização aumenta muito o número de elementos combináveis que o ambiente de execução ignora durante a recomposição. Sem a memorização, é muito mais provável que o ambiente de execução aloque uma nova lambda para qualquer elemento combinável que receba um parâmetro lambda durante a recomposição. Como resultado, a nova lambda tem parâmetros que não são iguais à última composição. Isso resulta na recomposição.
Evitar a memorização
Se você tiver uma lambda que não quer armazenar em cache, use a anotação
@DontMemoize
.
val lambda = @DontMemoize {
...
}
Tamanho do APK
Quando compilados, os elementos combináveis que podem ser pulados resultam em mais código gerado do que
elementos combináveis que não podem ser pulados. Com o salto forte ativado, o compilador
marca quase todos os elementos combináveis como saltáveis e envolve todos os lambdas em um
remember{...}
. Por isso, ativar o modo de rejeição avançada tem um impacto muito pequeno
no tamanho do APK do seu aplicativo.
A ativação de pulos fortes no Now in Android (link em inglês) aumentou o tamanho do APK em 4 KB. A diferença no tamanho depende em grande parte do número de elementos combináveis não ignoráveis que estavam presentes no app, mas deve ser relativamente pequena.