Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Junte-se a nós no Amazon Web Services re:Invent 2024! Saiba como usar o MongoDB para casos de uso de AI .
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Idiomaschevron-right
Kotlinchevron-right

StartActivityForResult está obsoleto!

Mohit Sharma2 min read • Published Sep 14, 2021 • Updated May 12, 2022
Kotlin
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Artigo
star-empty
star-empty
star-empty
star-empty
star-empty

Introdução

O Android tem estado na borda da evolução por um tempo recentemente, com atualizações para androidx.activity:activity-ktx para 1.2.0. Ele depreciou startActivityForResult em favor de registerForActivityResult.
Foi um dos primeiros fundamentos que qualquer desenvolvedor Android aprendeu e a espinha dorsal da maneira de comunicação do Android entre dois componentes. O design da API era simples o suficiente para ser iniciado rapidamente, mas tinha seus contras, como a dificuldade de encontrar o chamador em aplicativos do mundo real (exceto cmd+F no projeto 😂), obter resultados no fragmento, resultados perdidos se o componente é recriado, entra em conflito com o mesmo código de solicitação, etc.
Vamos tentar entender como usar a nova API com alguns exemplos.

Exemplo 1: a atividade A chama a atividade B para o resultado

Antiga escola:
1// Caller
2val intent = Intent(context, Activity1::class.java)
3startActivityForResult(intent, REQUEST_CODE)
4
5// Receiver
6override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
7 super.onActivityResult(requestCode, resultCode, data)
8 if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE) {
9 val value = data?.getStringExtra("input")
10 }
11}
Novo Caminho:
1// Caller
2val intent = Intent(context, Activity1::class.java)
3getResult.launch(intent)
4
5// Receiver
6private val getResult =
7 registerForActivityResult(
8 ActivityResultContracts.StartActivityForResult()
9 ) {
10 if (it.resultCode == Activity.RESULT_OK) {
11 val value = it.data?.getStringExtra("input")
12 }
13 }
Como você deve ter notado, registerForActivityResult utiliza dois parâmetros. O primeiro define o tipo de ação/interação necessária (ActivityResultContracts) e o segundo é uma função de chamada de resposta onde obtemos o resultado.
Não mudou muito, não é mesmo? Vamos verificar outro exemplo.

Exemplo 2: Inicie um componente externo, como a câmera, para obter a imagem:

1//Caller
2getPreviewImage.launch(null)
3
4//Receiver
5private val getPreviewImage = registerForActivityResult(ActivityResultContracts.TakePicture { bitmap ->
6 // we get bitmap as result directly
7})
O snippet acima é o código completo que obtém uma imagem de visualização da câmera. Não há necessidade de código de solicitação de permissão, pois isso é feito automaticamente para nós!
Outro benefício de usar a nova API é que ela força os desenvolvedores a usar o contrato correto. Por exemplo, com ActivityResultContracts.TakePicture() — que retorna a imagem completa — você precisa passar um URI como parâmetro para launch, o que reduz o tempo de desenvolvimento e a chance de erros.
Outros contratos padrão disponíveis podem ser encontrados em aqui.

Exemplo 3: o fragmento A chama a Atividade B para o resultado

Esse foi outro problema com o sistema antigo, sem nenhuma implementação limpa disponível, mas a nova API funciona de forma consistente em atividades e fragmentos. Portanto, referenciamos e adicionamos o trecho do exemplo 1 aos nossos fragmentos.

Exemplo 4: receber o resultado em uma classe não Android

Maneira antiga: .
Com a nova API, isso é possível usando ActivityResultRegistry diretamente.
1class MyLifecycleObserver(private val registry: ActivityResultRegistry) : DefaultLifecycleObserver {
2
3 lateinit var getContent: ActivityResultLauncher<String>
4
5 override fun onCreate(owner: LifecycleOwner) {
6 getContent = registry.register("key", owner, GetContent()) { uri ->
7 // Handle the returned Uri
8 }
9 }
10
11 fun selectImage() {
12 getContent.launch("image/*")
13 }
14}
15
16class MyFragment : Fragment() {
17 lateinit var observer: MyLifecycleObserver
18
19 override fun onCreate(savedInstanceState: Bundle?) {
20 // ...
21
22 observer = MyLifecycleObserver(requireActivity().activityResultRegistry)
23 lifecycle.addObserver(observer)
24 }
25
26 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
27 val selectButton = view.findViewById<Button>(R.id.select_button)
28
29 selectButton.setOnClickListener {
30 // Open the activity to select an image
31 observer.selectImage()
32 }
33 }
34}

Resumo

Encontrei registrarForActivityResult útil e limpo. Alguns dos prós, na minha opinião, são:
  1. Melhore a legibilidade do código, não é necessário lembrar de pular para onActivityResult() depois startActivityForResult.
  2. ActivityResultLauncher retornou do registerForActivityResult usado para iniciar componentes, definindo explicitamente o parâmetro de entrada para os resultados desejados.
  3. Foi removido o código padrão para solicitar permissão do usuário.
Espero que isso tenha sido informativo e tenha gostado de lê-lo.

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Artigo
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Exemplo de código

Construindo Splash Screen Nativamente, Android 12, Kotlin


May 12, 2022 | 3 min read
Tutorial

Desenvolvimento sem servidor com Kotlin, AWS Lambda e MongoDB Atlas


Aug 01, 2023 | 6 min read
Tutorial

Construindo um aplicativo Android


Aug 12, 2024 | 6 min read
Tutorial

Introdução ao desenvolvimento de backend em Kotlin usando Spring Boot 3 e MongoDB


Feb 21, 2023 | 6 min read
Sumário