Parcelables e pacotes

Objetos Parcelable e Bundle destinam-se ao uso em vários limites de processo, como com transações IPC/Binder, entre atividades com intents e para armazenar o estado temporário em mudanças de configuração. Esta página apresenta práticas recomendadas para o uso de objetos Parcelable e Bundle.

Observação:o Parcel não é um mecanismo de serialização de uso geral. Nunca armazene dados do Parcel em disco nem os envie pela rede.

Como enviar dados entre atividades

Quando um app cria um objeto Intent para usar em startActivity() ao iniciar uma nova atividade, o app pode transmitir parâmetros usando o método putExtra().

O snippet de código a seguir mostra um exemplo de como realizar essa operação.

val intent = Intent(this, MyActivity::class.java).apply {
    putExtra("media_id", "a1b2c3")
    // ...
}
startActivity(intent)

O SO organiza o Bundle subjacente do intent. Em seguida, o SO cria a nova atividade, separa os dados e transmite o intent para a nova atividade.

Recomendamos que você use a classe Bundle para definir primitivos conhecidos no SO em objetos Intent. A classe Bundle é altamente otimizada para empacotar e desempacotar usando lotes.

Em alguns casos, talvez seja necessário transmitir objetos complexos entre atividades ou preservá-los no estado da interface. Nesses casos, a classe personalizada precisa implementar o parcelable. Para apps modernos em Kotlin e Jetpack Compose, a abordagem recomendada é usar a anotação @Parcelize. Isso gera automaticamente a lógica de serialização necessária para processar seus dados com segurança ao usar pacotes. Essa é a mesma abordagem usada para processar seus dados ao usar rememberSaveable. Para mais informações sobre o uso de @Parcelize, consulte Gerador de implementação de Parcelable.

Ao enviar dados por meio de um intent, tenha o cuidado de limitar o tamanho dos dados a alguns KB. Enviar muitos dados pode fazer com que o sistema gere uma exceção TransactionTooLargeException.

Como enviar dados entre processos

Enviar dados entre processos é semelhante a fazer isso entre atividades. No entanto, ao enviar dados entre processos, recomendamos que você não use parcelables personalizados. Se você enviar um objeto Parcelable personalizado de um app para outro, precisará ter certeza de que a mesma versão da classe personalizada está presente nos apps de envio e de recebimento. Normalmente, isso pode ser uma biblioteca comum usada nos dois apps. Pode ocorrer um erro se o app tentar enviar um parcelable personalizado, porque o sistema não pode desempacotar uma classe de que não tenha conhecimento.

Por exemplo, um app pode definir um alarme usando a classe AlarmManager e usar um Parcelable personalizado no intent de alarme. Quando o alarme dispara, o sistema modifica o Bundle do intent de extras para adicionar uma contagem de repetição. Essa modificação pode fazer com que o sistema remova o Parcelable personalizado dos extras. Essa remoção, por sua vez, pode resultar na falha do app quando ele recebe o intent de alarme modificado, porque o app espera receber dados extras que não estão mais presentes.

O buffer de transação do Binder tem um tamanho fixo limitado, atualmente de 1 MB, que é compartilhado por todas as transações em andamento para o processo. Como esse limite está no nível do processo, e não no nível por atividade, isso inclui todas as transações do Binder no app, como startActivity, rememberSaveable (que usa onSaveInstanceState por baixo dos panos) e qualquer interação com o sistema. Quando o limite de tamanho é excedido, uma TransactionTooLargeException é gerada.

Para o caso específico de salvar o estado com rememberSaveable, a quantidade de dados precisa ser mantida pequena, porque o processo do sistema precisa manter os dados fornecidos enquanto o usuário puder navegar de volta para essa atividade, mesmo que o processo da atividade seja encerrado. Recomendamos que você mantenha o estado salvo para menos de 50 KB de dados.

Observação:no Android 7.0 (nível da API 24) ou versões mais recentes, o sistema gera uma TransactionTooLargeException como uma exceção de tempo de execução. Nas versões anteriores do Android, o sistema só mostra um aviso no logcat.