Extensões Android do ViewBinding vs Kotlin com visualizações sintéticas

38

Como o novo ViewBinding se compara às extensões Kotlin Android com ligações de vistas sintéticas?

Além dos NullSafety e TypeSafety fornecidos pelos novos ViewBindings, por que deveríamos considerar abandonar a maneira Kotlin de usar ligações sintéticas no Views?

O novo ViewBinding tem mais desempenho, pois gera a classe Binding antes da mão?

Rinav
fonte
Eu criei uma pergunta semelhante no discuss.kotlinlang. Se alguém tem pensamentos sobre o tema, fique à vontade para responder :)
xinaiz
11
Dê uma olhada no The Argument Over Kotlin Synthetics para obter mais informações.
Cheticamp

Respostas:

69

Vamos revisar os dois.


Configuração

Extensões Android do Kotlin

  1. Importe extensões sintéticas do layout apropriado: import kotlinx.android.synthetic.main.<layout>.*
  2. Referência vistas no código por meio de seus ids: textView.text = "Hello, world!". Estas extensões trabalhar em: Activities, Fragmentse Views.

Ver Encadernação

  1. Crie uma referência de ligação dentro da sua classe: private lateinit var binding YourClassBinding
  2. Inflar seu vinculativo binding = YourClassBinding.inflate(layoutInflater)dentro Activitydo onCreatee chamada setContentView(binding.root), ou inflá-lo em Fragment's onCreateView, em seguida, devolvê-lo:return binding.root
  3. Vistas de referência no código via ligação usando seus IDs binding.textView.text = "Hello, world!"

Digite segurança

As extensões Kotlin Android e ViewBinding são do tipo seguro por definição, porque as visualizações referenciadas já estão convertidas nos tipos apropriados.


Segurança nula

As extensões Kotlin Android e ViewBinding são seguras para nulos. ViewBinding não tem nenhuma vantagem aqui . No caso de KAE , se a visualização estiver presente apenas em algumas configurações de layout, o IDE indicará isso para você:

insira a descrição da imagem aqui

Então você o trata como qualquer outro tipo anulável no Kotlin, e o erro desaparece:

insira a descrição da imagem aqui


Aplicando alterações de layout

No caso das extensões Kotlin Android , as alterações de layout são instantaneamente convertidas em geração de extensões sintéticas, para que você possa usá-las imediatamente. No caso de ViewBinding , você deve criar seu projeto


Uso incorreto do layout

No caso das extensões Kotlin Android , é possível importar extensões sintéticas de layout incorretas, causando isso NullPointerException. O mesmo se aplica ao ViewBinding , pois podemos importar a Bindingclasse errada . Embora seja mais provável ignorar a importação incorreta do que o nome incorreto da classe, especialmente se o arquivo de layout tiver o nome de Activity/ Fragment/ View, então o ViewBinding está em vantagem aqui.


Resumo de KAE vs ViewBinding

  • Digite safety - Draw.
  • Segurança nula - Empate.
  • Código padrão - KAE vence. Na documentação das extensões do Kotlin Android :

O plug-in Kotlin Android Extensions nos permite obter a mesma experiência que temos com algumas dessas bibliotecas, sem precisar adicionar nenhum código extra.

  • Aplicando alterações de layout - o KAE vence. As alterações são instantâneas, em contraste com o ViewBinding .
  • Uso incorreto do layout - o ViewBinding vence

Eu acho que há um grande equívoco sobre o ViewBinding substituir o KAE . As pessoas ouvem grandes palavras-chave e as repetem sem verificar previamente. Certamente, o ViewBinding é a melhor opção para o desenvolvimento de Java agora (substituto do ButterKnife ), mas não há pouca ou nenhuma vantagem sobre o KAE no Kotlin (consulte a seção Uso incorreto do layout ).

Nota lateral: Tenho certeza que as pessoas do DataBinding vão gostar do ViewBinding :)

xinaiz
fonte
Por que você não disse nada sobre o uso de variáveis DataBinding? Eu acho que é um recurso essencial parar de usar as referências de exibição. A propósito, você pode "lançar" seu modelo de visualização através de <include ... />tags, o que é outra grande vantagem.
Ircover 21/10/19
11
@Ircover A questão era sobre a comparsa do KAE e do ViewBinding. DataBinding não faz parte dessa pergunta.
Xinaiz 21/10/19
Opa, desculpe) Simples mal-entendido.
Ircover 21/10/19
11
@ BenLewis, se sua ligação definida como atrasada ainda tiver o mesmo problema. Isso significa que não importa o que você usa o KAE ou o ViewBinding, é necessário seguir algumas regras estritas ao escrever o código no fragmento.
Flavio
11
"Aplicando alterações de layout" - Ao usar o ViewBinding, você não precisa criar seu projeto. Após adicionar uma nova visualização com um ID, você pode instantaneamente "binding.myTextView ..".
Tayyab Mazhar 01/03
19

ViewBindingresolveu o maior problema de kotlinx.android.synthetic. Na syntheticassociação, se você definir sua exibição de conteúdo como um layout e digitar um ID que exista apenas em um layout diferente, o IDE permitirá que você complete automaticamente e adicione a nova instrução de importação. A menos que o desenvolvedor verifique especificamente se as instruções de importação importam apenas as visualizações corretas, não há uma maneira segura de verificar se isso não causará um problema de tempo de execução. Mas ViewBindingvocê deve usar seulayout objeto de ligação para acessar suas visualizações, para nunca invocar uma visualização em um layout diferente e, se quiser fazer isso, receberá um erro de compilação e não um erro de tempo de execução. Aqui está um exemplo.

Criamos dois layouts chamados activity_maine activity_otherassim:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <TextView
        android:id="@+id/message_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</RelativeLayout>

activity_other.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                >

    <TextView
        android:id="@+id/message_other"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</RelativeLayout>

Agora, se você escrever sua atividade assim:

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_other.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //Application will crash because "message_other" doesn't exist in "activity_main"
        message_other.text = "Hello!"
    }
}

seu código será compilado sem nenhum erro, mas seu aplicativo falhará em tempo de execução. Porque a visualização com message_otherid não existe activity_maine o compilador não verificou isso. Mas se você usar ViewBindingassim:

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        //This code will never compile and the IDE shows you an error
        binding.message_other.text = "Hello!"
    }
}

seu código nunca será compilado e Android Studiomostra um erro na última linha.

Squti
fonte
11
Você também pode usar o LayoutInflater para aumentar o modo de exibição e, em seguida, referenciar seus campos definidos por meio de variável.
NapoleonTheCake
4
Isso parece muito improvável de acontecer no cenário da vida real.
Bencri 17/02
11
O exemplo não faz sentido. Você o usou incorretamente. Por que você importaria a coisa incorreta (activity_other)? Toda estrutura que você usa incorretamente pode causar problemas.
desenvolvedor android
2

O kotlinx.android.synthetic não é mais uma prática recomendada, disse o google em uma mensagem de confirmação "one of Reddit thread

https://android-review.googlesource.com/c/platform/frameworks/support/+/882241 "

O Synthetics não é desenvolvido pelo google, é parte da extensão android do kotlin, criada por JetBrains e, gradualmente, os desenvolvedores do google android começaram a substituir o Synthetics pelo ViewBindins em suas demos e códigos-fonte.

"Agora vem a pergunta, qual devemos levar em consideração."

Segundo o google (View binding, ButterKnife, Kotlin synthetics), essas bibliotecas são usadas com sucesso por muitos aplicativos e resolvem o mesmo problema.

No entanto, para a maioria dos aplicativos, o Google recomenda experimentar a vinculação de exibição em vez dessas bibliotecas .

Imagem de referência anexada para limpar as coisas rapidamente. insira a descrição da imagem aqui

No entanto, se você quiser entrar no departamento, pode seguir o link abaixo. https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc

SourabhTech
fonte
2
1. Sempre com segurança nula - a ligação de exibição ainda falhará se usada antes da inflação ou após o término do ciclo de vida da exibição - nada diferente dos sintéticos - deve ser VERMELHO para o ViewBinding. 2. Apenas os IDs de referência do layout atual - isso é verdade, mas o IDE indica de qual layout você deseja importar o ID fornecido, portanto, não é um grande problema. 3. Suporta Kotlin e Java - argumento ruim, se você pode usar o Kotlin no desenvolvimento do Android, por que usar o Java. 4. Quantidade de código necessária - os sintéticos Kotlin têm a menor quantidade, devem estar muito baixos na tabela.
xinaiz 11/03
@xinaiz Por que você o está usando antes de inflar, siga a maneira correta de usá-lo, caso contrário, você enfrentará os problemas. Você já passou pelo link antes do voto
negativo
Sim, eu li isso há algum tempo. Não o uso antes de inflar, apenas estou dizendo que é possível. "Maneira correta" implica que existem riscos, certo? Além disso, você pulou or after view lifecycle endsparte?
xinaiz 11/03
@xinaiz 2.Mas existe a chance de usar uma identificação incorreta se o projeto for maior e também para o mesmo nome de recurso se vários desenvolvedores estiverem trabalhando no projeto. 3.Sim, pode haver um requisito de projeto no qual você deve usar java e kotlin (se o projeto já foi desenvolvido em java e iniciou a intrigação com o kotlin, então definitivamente ajuda) já está lá em Gradle, então obviamente levou menos código.
SourabhTech 11/03
11
Em resposta a 4. Qual biblioteca? Está ativado por padrão. É argumento sobre apply plugin: 'kotlin-android-extensions'vs viewBinding { enabled = true }. Pouca diferença.
xinaiz 11/03