Phần mở rộng Android ViewBinding vs Kotlin với chế độ xem tổng hợp


38

Làm thế nào để ViewBinding mới so sánh với Tiện ích mở rộng Android của Kotlin với các ràng buộc về chế độ xem tổng hợp?

Ngoài hình thức NullSafe và TypeSafe được cung cấp bởi ViewBindings mới, tại sao chúng ta nên xem xét từ bỏ cách thức sử dụng các ràng buộc tổng hợp trên Chế độ xem.

Là ViewBinding mới có hiệu suất cao hơn vì nó tạo ra lớp Binding trước khi sử dụng?


Tôi đã tạo ra một số câu hỏi tương tự trên thảo luận.kotlinlang. Nếu bất cứ ai có suy nghĩ về chủ đề này, vui lòng trả lời :)
xinaiz

1
Hãy xem The Argument Over Kotlin Synthetic để có thêm thông tin.
Cheticamp

Câu trả lời:


69

Hãy xem lại hai.


Cấu hình

Tiện ích mở rộng Android của Kotlin

  1. Nhập phần mở rộng tổng hợp bố trí thích hợp: import kotlinx.android.synthetic.main.<layout>.*
  2. Lượt xem tham chiếu trong mã thông qua id của họ : textView.text = "Hello, world!". Các tiện ích mở rộng này hoạt động trên : Activities, FragmentsViews.

Xem đóng sách

  1. Tạo tham chiếu ràng buộc trong lớp của bạn: private lateinit var binding YourClassBinding
  2. Thổi phồng ràng buộc của bạn binding = YourClassBinding.inflate(layoutInflater)bên Activity's onCreatevà cuộc gọi setContentView(binding.root), hoặc thổi phồng nó trong Fragment' s onCreateViewsau đó trả lại:return binding.root
  3. Lượt xem tham chiếu trong mã thông qua liên kết sử dụng id của họ binding.textView.text = "Hello, world!"

Loại an toàn

Theo định nghĩa, Phần mở rộngViewBinding của Kotlin là loại an toàn, bởi vì các chế độ xem được tham chiếu đã được chuyển sang các loại thích hợp.


An toàn vô hiệu

Phần mở rộng của Kotlin AndroidViewBinding đều an toàn. ViewBinding không có bất kỳ lợi thế nào ở đây . Trong trường hợp của KAE , nếu chế độ xem chỉ xuất hiện trong một số cấu hình bố cục, IDE sẽ chỉ ra điều đó cho bạn:

nhập mô tả hình ảnh ở đây

Vì vậy, bạn chỉ coi nó như bất kỳ loại nullable nào khác trong Kotlin và lỗi sẽ biến mất:

nhập mô tả hình ảnh ở đây


Áp dụng thay đổi bố cục

Trong trường hợp Tiện ích mở rộng Android của Kotlin , bố cục thay đổi ngay lập tức chuyển sang thế hệ tiện ích mở rộng tổng hợp, vì vậy bạn có thể sử dụng chúng ngay lập tức. Trong trường hợp ViewBinding , bạn phải xây dựng dự án của mình


Cách sử dụng bố trí không chính xác

Trong trường hợp Tiện ích mở rộng Android của Kotlin , có thể nhập các tiện ích mở rộng tổng hợp bố cục không chính xác, do đó gây ra NullPointerException. Điều tương tự cũng áp dụng cho ViewBinding , vì chúng ta có thể nhập sai Bindinglớp. Mặc dù, có nhiều khả năng bỏ qua việc nhập sai so với tên lớp không chính xác, đặc biệt là nếu tệp bố cục được đặt tên tốt sau Activity/ Fragment/ View, vì vậy ViewBinding có ưu thế ở đây.


Tóm tắt về KAE vs ViewBinding

  • Loại an toàn - Vẽ.
  • Null an toàn - Vẽ.
  • nồi hơi - KAE thắng. Từ tài liệu mở rộng Android của Kotlin :

Plugin Phần mở rộng Android của Kotlin cho phép chúng tôi có được trải nghiệm tương tự với một số thư viện này mà không cần phải thêm bất kỳ mã nào.

  • Áp dụng thay đổi bố cục - KAE thắng. Các thay đổi ngay lập tức trái ngược với ViewBinding .
  • Cách sử dụng bố cục không chính xác - ViewBinding thắng

Tôi nghĩ có một quan niệm sai lầm lớn về việc ViewBinding thay thế cho KAE . Mọi người nghe các từ khóa lớn và lặp lại chúng mà không cần xác minh trước. Chắc chắn, ViewBinding là tùy chọn tốt nhất để phát triển Java ngay bây giờ (thay thế cho ButterKnife ), nhưng không có hoặc có ít lợi thế so với KAE trong Kotlin (xem phần Sử dụng bố cục không chính xác ).

Lưu ý bên lề: Tôi chắc chắn mọi người DataBinding sẽ thích ViewBinding :)


Tại sao bạn không nói gì về việc sử dụng các biến trong DataBinding? Tôi nghĩ đó là tính năng thiết yếu để ngừng sử dụng tham chiếu xem. Nhân tiện, bạn có thể "ném" mô hình xem của mình thông qua <include ... />các thẻ, đó là một lợi thế lớn khác.
Irpack 21/10/19

1
@Ircover Câu hỏi là về sự kết hợp của KAE và ViewBinding. DataBinding không phải là một phần của câu hỏi đó.
xinaiz

Rất tiếc, xin lỗi) Hiểu lầm đơn giản.
Irpack 21/10/19

1
@BenLewis nếu ràng buộc của bạn được xác định là lateinit bạn vẫn gặp vấn đề tương tự. Điều đó có nghĩa là không có đồng hồ nào bạn sử dụng KAE hoặc ViewBinding, bạn phải tuân theo một số quy tắc nghiêm ngặt khi viết mã trong đoạn.
Flavio

1
"Áp dụng thay đổi bố cục" - Khi sử dụng ViewBinding, bạn không phải xây dựng dự án của mình, sau khi thêm chế độ xem mới với id, bạn có thể ngay lập tức thực hiện "bind.myTextView ..".
Tayyab Mazhar

19

ViewBindinggiải quyết vấn đề lớn nhất của kotlinx.android.synthetic. Trong syntheticràng buộc nếu bạn đặt chế độ xem nội dung của mình thành bố cục, sau đó nhập id chỉ tồn tại ở một bố cục khác, IDE cho phép bạn tự động hoàn tất và thêm câu lệnh nhập mới. Trừ khi nhà phát triển kiểm tra cụ thể để đảm bảo báo cáo nhập khẩu của họ chỉ nhập các chế độ xem chính xác, không có cách nào an toàn để xác minh rằng điều này sẽ không gây ra sự cố thời gian chạy. Nhưng trong ViewBindingbạn nên sử dụng layoutđối tượng ràng buộc của mình để truy cập vào các khung nhìn của nó để bạn không bao giờ gọi đến một khung nhìn trong một bố cục khác và nếu bạn muốn làm điều này, bạn sẽ nhận được một lỗi biên dịch không phải là lỗi thời gian chạy. Đây là một ví dụ.

Chúng tôi tạo ra hai bố cục được gọi activity_mainactivity_othernhư vậy:

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>

Bây giờ nếu bạn viết hoạt động của bạn như thế này:

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

mã của bạn sẽ biên dịch mà không có bất kỳ lỗi nào nhưng ứng dụng của bạn sẽ bị sập khi chạy. Bởi vì khung nhìn với message_otherid không tồn tại activity_mainvà trình biên dịch đã không kiểm tra điều này. Nhưng nếu bạn sử dụng ViewBindingnhư vậy:

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

mã của bạn sẽ không bao giờ biên dịch và Android Studiohiển thị cho bạn một lỗi trong dòng cuối cùng.


1
Bạn cũng có thể sử dụng LayoutInflater để tăng cường View và sau đó tham chiếu các trường được xác định của nó thông qua biến.
NapoleonThe

4
Điều này dường như rất khó xảy ra trong kịch bản đời thực.
Bencri

1
Ví dụ này không có ý nghĩa. Bạn đã sử dụng nó không chính xác. Tại sao bạn nhập những thứ không chính xác (Activity_other)? Mỗi khung mà bạn sử dụng không chính xác có thể gây ra vấn đề.
nhà phát triển Android

2

kotlinx.android.sy merg không còn là một thông lệ được đề xuất, được google cho biết trong một thông điệp cam kết "một trong các chủ đề Reddit

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

Tổng hợp không được phát triển bởi google, đó là một phần của tiện ích mở rộng kotlin android do JetBrains tạo ra và dần dần các nhà phát triển google google bắt đầu thay thế Tổng hợp bằng ViewBindins trong các bản demo và mã nguồn của họ.

"Bây giờ câu hỏi đến, cái nào chúng ta phải xem xét nó."

Theo google (Xem ràng buộc, tổng hợp ButterKnife, Kotlin) các thư viện này được sử dụng thành công bởi nhiều ứng dụng và giải quyết cùng một vấn đề.

Nhưng đối với hầu hết các ứng dụng, google khuyên bạn nên thử xem ràng buộc thay vì các thư viện này Bởi vì liên kết xem cung cấp tra cứu chế độ xem ngắn gọn, an toàn hơn.

Đính kèm hình ảnh tham khảo để xóa mọi thứ một cách nhanh chóng. nhập mô tả hình ảnh ở đây

Tuy nhiên nếu bạn muốn vào phòng, bạn có thể theo liên kết dưới đây. https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc


2
1. Luôn không an toàn - Liên kết xem vẫn sẽ bị sập nếu được sử dụng trước khi lạm phát hoặc sau khi vòng đời của chế độ xem kết thúc - không có gì khác với tổng hợp - phải là ĐỎ cho ViewBinding. 2. Chỉ các id tham chiếu từ bố cục hiện tại - điều đó đúng, nhưng IDE chỉ ra bố cục bạn muốn nhập id đã cho, vì vậy đó không phải là vấn đề lớn. 3. Hỗ trợ Kotlin & Java - đối số xấu, nếu bạn có thể sử dụng Kotlin trong phát triển Android thì tại sao lại sử dụng Java. 4. Số lượng mã cần thiết - Tổng hợp của Kotlin có số lượng thấp nhất, nên rất thấp trong bảng.
xinaiz

@xinaiz Tại sao bạn sử dụng nó trước khi bơm hơi, hãy làm theo cách chính xác để sử dụng nó nếu không chắc chắn bạn sẽ phải đối mặt với các vấn đề. Bạn đã đi qua liên kết trước khi downvote và đăng bình luận vừa rồi.com/androiddevelopers/ trên
SourabhTech

Vâng, tôi đã đọc nó một thời gian trước đây. Tôi không sử dụng nó trước khi thổi phồng, tôi chỉ nói rằng nó có thể. "Cách chính xác" ngụ ý rằng có những rủi ro, phải không? Ngoài ra, bạn bỏ qua or after view lifecycle endsmột phần?
xinaiz

@xinaiz 2.Nhưng có cơ hội sử dụng id sai nếu dự án lớn hơn và cũng có cùng tên tài nguyên nếu nhiều nhà phát triển làm việc trên dự án. 3. Có thể có một yêu cầu dự án khi bạn phải sử dụng cả java và kotlin (Nếu dự án đã được phát triển trong java và bắt đầu xâm nhập với kotlin thì chắc chắn nó sẽ giúp) 4. Đối với Tổng hợp, bạn phải nhập thư viện riêng nhưng để xem ràng buộc Nó đã có ở Gradle, nên rõ ràng là nó lấy mã ít hơn.
SourabhTech

1
Đáp lại 4. Thư viện nào? Nó được bật theo mặc định. Đó là lý luận về apply plugin: 'kotlin-android-extensions'vs viewBinding { enabled = true }. Không có nhiều khác biệt.
xinaiz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.