[android] 합성 뷰가있는 ViewBinding 및 Kotlin Android 확장

새로운 ViewBindingKotlin Android Extensions 와 합성 뷰 바인딩을 어떻게 비교 합니까?

새로운 ViewBindings에서 제공하는 NullSafety 및 TypeSafety를 제외하고 왜 우리는 Views에 합성 바인딩을 사용하는 Kotlin 방식을 버리는 것을 고려해야합니까?

새로운 ViewBinding은 미리 Binding 클래스를 생성하므로 성능이 더 좋습니까?



답변

두 가지를 살펴 보자.


구성

코 틀린 안드로이드 확장

  1. 적절한 레이아웃 합성 확장을 가져옵니다. import kotlinx.android.synthetic.main.<layout>.*
  2. ID를 통한 코드의 참조 뷰 : textView.text = "Hello, world!". 이 확장은 Activities, Fragments및 에서 작동합니다 Views.

바인딩보기

  1. 클래스 내에 바인딩 참조를 작성하십시오. private lateinit var binding
    YourClassBinding
  2. 당신의 바인딩을 부풀려 binding = YourClassBinding.inflate(layoutInflater)내부 ActivityonCreate와 전화를 setContentView(binding.root)하거나에서 팽창 Fragments ‘를 onCreateView반환 한 후 :return binding.root
  3. ID를 사용한 바인딩을 통한 코드의 참조 뷰 binding.textView.text = "Hello, world!"

타입 안전

Kotlin Android ExtensionsViewBinding 은 참조 된 뷰가 이미 적절한 유형으로 캐스트 되었기 때문에 정의에 따라 유형이 안전합니다.


널 안전

Kotlin Android ExtensionsViewBinding 은 모두 null 안전합니다. ViewBinding은 여기서 이점이 없습니다 . 의 경우 KAE ,보기는 일부 레이아웃 구성에서, IDE가 당신을 위해 지적 할 것이다 존재하는 경우 :

여기에 이미지 설명을 입력하십시오

따라서 Kotlin에서 다른 nullable 유형으로 취급하면 오류가 사라집니다.

여기에 이미지 설명을 입력하십시오


레이아웃 변경 사항 적용

의 경우에는 코 틀린 안드로이드 확장 하면 바로 사용할 수 있도록 레이아웃 변경은 즉시, 합성 확장 세대로 번역합니다. ViewBinding의 경우 프로젝트를 빌드해야합니다


잘못된 레이아웃 사용법

Kotlin Android Extensions의 경우 잘못된 레이아웃 합성 확장을 가져 와서 발생할 수 NullPointerException있습니다. 잘못된 클래스를 가져올 수 있기 때문에 ViewBinding 에도 동일하게 적용됩니다 Binding. 비록 레이아웃 파일의 이름이 Activity/ Fragment/로 잘 지정된 경우 특히 잘못된 클래스 이름보다 잘못된 가져 오기를 간과 할 가능성이 높기View 때문에 ViewBinding 이 여기에 우세합니다.


KAE와 ViewBinding의 요약

  • 안전 유형 -그리기.
  • Null 안전 -그리기.
  • 상용구 코드KAE의 승리. Kotlin Android Extensions 문서에서 :

Kotlin Android Extensions 플러그인을 사용하면 추가 코드를 추가하지 않고도 이러한 라이브러리 중 일부와 동일한 경험을 얻을 수 있습니다.

  • 레이아웃 변경 적용KAE는 승리합니다. ViewBinding 과 대조적으로 변경 사항이 즉시 적용됩니다 .
  • 잘못된 레이아웃 사용ViewBinding 승리

ViewBindingKAE를 대체하는 것에 대한 오해가 있다고 생각 합니다. 사람들은 큰 키워드를 듣고 미리 확인하지 않고 반복합니다. 물론 ViewBinding 은 Java 개발에 가장 적합한 옵션 이지만 ( ButterKnife의 대체 ) Kotlin의 KAE 보다 이점이 적거나 거의 없습니다 ( 잘못된 레이아웃 사용 섹션 참조).

참고 사항 :
DataBinding 사람들이 ViewBinding을 좋아할 것이라고 확신합니다. 🙂


답변

ViewBinding의 가장 큰 문제를 해결했습니다 kotlinx.android.synthetic. 에서 synthetic당신이 레이아웃에 콘텐츠보기를 설정하면 바인딩 만이 다른 레이아웃에 존재하는 ID를 입력 한 IDE는 자동 완성과 새로운 import 문을 추가 할 수 있습니다. 개발자가 import 문이 올바른 뷰만 가져 오는지 확인하지 않으면 런타임 문제가 발생하지 않는지 확인할 수있는 안전한 방법이 없습니다. 그러나 바인딩 객체를 사용하여 뷰에 액세스 ViewBinding해야 layout하므로 다른 레이아웃의 뷰를 호출하지 않아야하며이를 수행하려면 런타임 오류가 아닌 컴파일 오류가 발생합니다. 다음은 예입니다.

우리는 두 가지 레이아웃을 생성 activity_main하고 activity_other이렇게 좋아합니다 :

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>

이제 다음과 같이 활동을 작성하십시오.

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!"
    }
}

코드는 오류없이 컴파일되지만 런타임에 응용 프로그램이 중단됩니다. message_otherid가 있는 뷰가 존재하지 않고 activity_main컴파일러가 이것을 확인하지 않았기 때문입니다. 그러나 당신 ViewBinding이 그렇게 사용한다면 :

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!"
    }
}

코드는 컴파일되지 않으며 Android Studio마지막 줄에 오류를 표시합니다.


답변

kotlinx.android.synthetic은 더 이상 권장되지 않습니다. 하나의 커밋 메시지에서 “Redit 스레드 중 하나”

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

Synthetics 는 Google이 개발하지 않았으며 JetBrains가 제작 한 kotlin 안드로이드 확장의 일부이며 점차 Google Android 개발자는 데모 및 소스 코드에서 Synthetics를 ViewBindins로 대체하기 시작했습니다.

“지금 우리가 고려해야 할 질문이 있습니다.”

구글 (View binding, ButterKnife, Kotlin synthetics)에 따르면이 라이브러리는 많은 앱에서 성공적으로 사용되며 동일한 문제를 해결합니다.

그러나 대부분의 앱에서 이러한 라이브러리 대신 뷰 바인딩을 사용해 보는 것이 좋습니다. 뷰 바인딩은 더 안전하고 간결한 뷰 조회를 제공하기 때문입니다.

사물을 빠르게 제거하기 위해 참조 이미지를 첨부했습니다.
여기에 이미지 설명을 입력하십시오

그러나 부서에 가고 싶다면 아래 링크를 따라갈 수 있습니다.
https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc


답변