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


38

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

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

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


Discussion.kotlinlang에 대해 다소 비슷한 질문 을 만들었습니다 . 누구든지 주제에 대한 생각이 있다면, 자유롭게 응답하십시오 :)
xinaiz

1
Kotlin Synthetics에 대한 논증 을 좀 더 배경 으로 살펴보십시오 .
Cheticamp

답변:


69

두 가지를 살펴 보자.


구성

코 틀린 안드로이드 확장

  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을 좋아할 것이라고 확신합니다. :)


변수 사용에 대해 왜 말하지 않았 DataBinding습니까? 뷰 참조 사용을 중단하는 것이 필수적인 기능이라고 생각합니다. 그건 그렇고, <include ... />태그를 통해 뷰 모델을 "투척"할 수 있으며 이는 또 다른 큰 장점입니다.
Ircover

1
@Ircover KAE와 ViewBinding의 비교에 대한 질문이었습니다. DataBinding은 그 질문의 일부가 아닙니다.
xinaiz

죄송합니다. 간단한 오해입니다.
Ircover

1
@BenLewis 바인딩이 lateinit로 정의 된 경우에도 여전히 동일한 문제가 있습니다. 즉, KAE 또는 ViewBinding을 사용하는 미터가 없어도 조각에 코드를 작성할 때 몇 가지 엄격한 규칙을 따라야합니다.
Flavio

1
"레이아웃 변경 사항 적용"-ViewBinding을 사용할 때 ID를 사용하여 새보기를 추가 한 후 즉시 "binding.myTextView .."를 수행 할 수 있습니다.
Tayyab Mazhar

19

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마지막 줄에 오류를 표시합니다.


1
LayoutInflater를 사용하여 View를 확장 한 다음 변수를 통해 정의 된 필드를 참조 할 수도 있습니다.
NapoleonTheCake

4
이것은 실제 시나리오에서 일어날 가능성이 거의없는 것 같습니다.
Bencri

1
이 예는 이해가되지 않습니다. 잘못 사용했습니다. 왜 잘못된 것을 가져 옵니까 (activity_other)? 잘못 사용하는 모든 프레임 워크는 문제를 일으킬 수 있습니다.
안드로이드 개발자

2

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


2
1. 항상 null 안전 – 인플레이션 이전 또는 뷰 수명주기 종료 후 사용 된 경우 뷰 바인딩은 여전히 ​​충돌합니다. 합성과 다른 점은 ViewBinding에 대해 빨간색이어야합니다. 2. 현재 레이아웃의 id 만 참조하십시오-사실이지만 IDE는 주어진 id를 가져 오려는 레이아웃을 지적하므로 큰 문제는 아닙니다. 3. Kotlin & Java 지원-안드로이드 개발에서 Kotlin을 사용할 수 있다면 Java를 사용하는 이유가 잘못되었습니다. 4. 필요한 코드 양-Kotlin 합성 물질의 양이 가장 적으므로 표에서 매우 낮아야합니다.
xinaiz

@xinaiz 팽창하기 전에 사용하는 이유는 올바른 방법을 따라 사용하십시오. 그렇지 않으면 문제가 발생할 수 있습니다. downvote 전에 코멘트를 통해 코멘트를 게시 한 적이 있습니까? medium.com/androiddevelopers/…
SourabhTech

예, 얼마 전에 읽었습니다. 팽창시키기 전에 그것을 사용하지 않고 단지 가능하다고 말하고 있습니다. "올바른 방법"은 위험이 있음을 의미합니다. 또한, 당신은 or after view lifecycle ends부분 을 건너 뛰었다 ?
xinaiz

@ xinaiz 2.하지만 프로젝트가 더 큰 경우 잘못된 ID를 사용하고 다중 개발자가 프로젝트에서 작업하는 경우 동일한 리소스 이름을 사용할 가능성이 있습니다. 3. 예, Java와 kotlin을 모두 사용해야하는 프로젝트 요구 사항이있을 수 있습니다 (프로젝트가 이미 Java로 개발되어 kotlin으로 관개를 시작한 경우 확실히 도움이됩니다) 4. Synthetics의 경우 별도의 라이브러리를 가져와야하지만 뷰 바인딩 이미 Gradle에 있으므로 코드가 덜 사용됩니다.
SourabhTech

1
4. What library? (님의 질문에 답변) 기본적으로 활성화되어 있습니다. apply plugin: 'kotlin-android-extensions'vs 에 대한 논쟁 viewBinding { enabled = true }입니다. 큰 차이는 없습니다.
xinaiz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.