Nova API de Activity Result do Android
Diga adeus ao "onActivityResult"
Não é novidade que ao desenvolver um app temos a necessidade de trocar dados entre activities. Em muitos casos precisamos de uma resposta de volta, um result da Activity que acabamos de abrir, seja em um caso de uso simples como abrir a câmera para capturar uma imagem, ou até mesmo dentro de uma funcionalidade que faz parte dos casos de uso do nosso app.
The old way
A maneira conhecida por nós, desenvolvedores de apps Android, é criar uma Intent
, um requestCode
, chamar o startActivityForResult
passando-os, e sobrescrever o método onActivityResult
para aguardar uma resposta (na prática, um resultCode
e uma Intent
.
Aparentemente simples, não é? Então o que melhorar nessa abordagem? 🤔
Todos nós sabemos que o código está sempre crescendo, dia após dia, código e mais código, e o que facilmente acontece é que o método onActivityResult
começa a "inflar" de condicionais (if/else, when) 😅.
The new way — API Activity Result
A nova API de Activity Result foi adicionada no AndroidX nos artefatos de Activity 1.2.0-alpha02
e Fragment 1.3.0-alpha02
. Ainda não temos uma versão release, mas temos a primeira release candidate, rc01
.
Para começar a usar essa nova API, precisamos adicionar estas duas dependências em nosso build.gradle
:
dependencies {
implementation 'androidx.activity:activity:1.2.0-rc01'
implementation 'androidx.fragment:fragment:1.3.0-rc01'
...
}
Após adicionar as dependências, em sua activity ou fragment, está disponível o acesso ao registerForActivityResult
que recebe um ActivityResultContract
e nos entrega um callback onde esperamos pelo result. Veja o exemplo anterior modificado para usar a API de Activity Result:
Parece não mudar muita coisa, certo? Na realidade mudou sim! O uso de ActivityResultContract
nos deu mais flexibilidade e mais organização do código. Vamos explorar um pouco mais para entender o que são esses contratos.
Um contrato especifica que uma activity pode ser chamada com um input de um tipo e produz um output de outro tipo.
Podemos criar contratos especializados com entradas e saídas bem definidas, e usá-los em nossas activities ou fragments.
No exemplo acima, criamos um contrato para iniciar a activity ProductsActivity
recebendo uma String
em sua Intent
e esperar por um objeto Product
como resposta (result).
Contratos prontos, "pegue e use"
Também existem contratos prontos que podemos usar para facilitar o nosso dia a dia (em androidx.activity.result.contract.ActivityResultContract
).
// default start for result
StartActivityForResult()
// permission
RequestMultiplePermissions()
RequestPermission()
// camera and picture
TakePicturePreview()
TakePicture()
TakeVideo()
PickContact()
// document
CreateDocument()
OpenDocumentTree()
OpenMultipleDocuments()
OpenDocument()
// content
GetMultipleContents()
GetContent()
Você ainda pode preferir usar o contrato StartActivityForResult
que recebe uma Intent
e devolve um ActivityResult
para não precisar de contratos especializados. Se esse for o seu caso, ainda pode criar uma extension para deixar mais simples obter o result.
Activities e Fragments implementam
ActivityResultCaller
.
Bom, para esse post era isso 😁 !
Se você aprendeu algo novo aqui, não deixe de compartilhar com outras pessoas desenvolvedoras que você conhece 🤗
Se quiser explorar mais, segue a documentação do Android abordando o tema: https://developer.android.com/training/basics/intents/result