ViewBinding vs Kotlin Android ส่วนขยายพร้อมมุมมองสังเคราะห์


38

ViewBindingใหม่เปรียบเทียบกับKotlin Android Extensionsกับการโยงมุมมองสังเคราะห์อย่างไร

นอกเหนือจากรูปแบบ NullSafety และ TypeSafety ที่ได้รับจาก ViewBindings ใหม่ทำไมเราจึงควรพิจารณาวิธี Kotlin ในการใช้การเชื่อมโยงสังเคราะห์ใน Views

ViewBinding ใหม่มีประสิทธิภาพมากกว่าหรือไม่เนื่องจากสร้างคลาส Binding ไว้ก่อนมือ?


ฉันสร้างคำถามที่คล้ายกันใน discuss.kotlinlang หากใครมีความคิดเกี่ยวกับหัวข้อนี้
อย่า

1
ลองดูที่The Argument Over Kotlin Syntheticsเพื่อทราบพื้นฐานเพิ่มเติม
Cheticamp

คำตอบ:


69

ลองทบทวนทั้งสอง


องค์ประกอบ

Kotlin Android Extensions

  1. นำเข้านามสกุลสังเคราะห์ที่เหมาะสมเค้าโครง: import kotlinx.android.synthetic.main.<layout>.*
  2. textView.text = "Hello, world!"มุมมองในการอ้างอิงรหัสผ่านรหัสของพวกเขา ส่วนขยายเหล่านี้ทำงานเมื่อ: Activities, และFragmentsViews

ดูการเชื่อม

  1. สร้างการอ้างอิงที่มีผลผูกพันภายในชั้นเรียนของคุณ: private lateinit var binding YourClassBinding
  2. พองผูกพันของคุณbinding = YourClassBinding.inflate(layoutInflater)ภายในActivity's onCreateและโทรsetContentView(binding.root)หรือขยายในFragment' s onCreateViewแล้วส่งกลับมา:return binding.root
  3. มุมมองการอ้างอิงในรหัสผ่านการผูกโดยใช้รหัสของพวกเขา binding.textView.text = "Hello, world!"

ประเภทความปลอดภัย

Kotlin Android ExtensionsและViewBindingเป็นประเภทที่ปลอดภัยตามคำนิยามเพราะมุมมองที่อ้างอิงจะถูกใช้ในประเภทที่เหมาะสมแล้ว


ปลอดภัยเป็นศูนย์

Kotlin Android ExtensionsและViewBindingนั้นปลอดภัยทั้งคู่ ViewBinding ไม่มีประโยชน์ใด ๆ ที่นี่ ในกรณีของKAEหากมุมมองมีอยู่เฉพาะในโครงร่างบางโครง IDE จะชี้ให้คุณเห็น:

ป้อนคำอธิบายรูปภาพที่นี่

ดังนั้นคุณจะถือว่าเป็นประเภท nullable อื่น ๆ ใน Kotlin และข้อผิดพลาดจะหายไป:

ป้อนคำอธิบายรูปภาพที่นี่


ใช้การเปลี่ยนแปลงโครงร่าง

ในกรณีของKotlin Android Extensionsการเปลี่ยนแปลงเลย์เอาต์จะแปลเป็นการสร้างส่วนขยายสังเคราะห์ทันทีเพื่อให้คุณสามารถใช้งานได้ทันที ในกรณีของViewBindingคุณต้องสร้างโครงการของคุณ


การใช้เค้าโครงไม่ถูกต้อง

ในกรณีของการKotlin Android ส่วนขยายNullPointerExceptionก็เป็นไปได้ที่จะนำเข้าส่วนขยายรูปแบบสังเคราะห์ที่ไม่ถูกต้องจึงก่อให้เกิด เช่นเดียวกับViewBindingเนื่องจากเราสามารถนำเข้าBindingคลาสที่ไม่ถูกต้อง แม้ว่าจะมีความเป็นไปได้มากกว่าที่จะมองข้ามการนำเข้าที่ไม่ถูกต้องมากกว่าชื่อคลาสที่ไม่ถูกต้องโดยเฉพาะอย่างยิ่งหากไฟล์เลย์เอาต์ได้รับการตั้งชื่อไว้อย่างดีหลังจากActivity/ Fragment/ Viewดังนั้นViewBindingจึงมีความโดดเด่นกว่าที่นี่


สรุป KAE กับ ViewBinding

  • ประเภทความปลอดภัย - วาด
  • ความปลอดภัยที่ว่างเปล่า - วาด
  • รหัส Boilerplate - KAEชนะ จากเอกสารประกอบ Kotlin Android Extensions :

ปลั๊กอินเสริม Kotlin Android ช่วยให้เราได้รับประสบการณ์เดียวกันกับที่เรามีกับห้องสมุดเหล่านี้บางส่วนโดยไม่ต้องเพิ่มรหัสพิเศษใด ๆ

  • ใช้การเปลี่ยนแปลงโครงร่าง - KAEชนะ มีการเปลี่ยนแปลงได้ทันทีในทางตรงกันข้ามกับViewBinding
  • การใช้เค้าโครงที่ไม่ถูกต้อง - ViewBindingชนะ

ผมคิดว่ามีเป็นความเข้าใจผิดใหญ่เกี่ยวกับViewBindingทดแทนเป็นอยู่สำหรับKAE ผู้คนได้ยินคำหลักขนาดใหญ่และทำซ้ำโดยไม่ตรวจสอบล่วงหน้า แน่นอนว่าViewBindingเป็นตัวเลือกที่ดีที่สุดสำหรับการพัฒนา Java ในตอนนี้ (แทนที่ButterKnife ) แต่ไม่มีข้อได้เปรียบเหนือKAEใน Kotlin (ดูส่วนการใช้เลย์เอาต์ที่ไม่ถูกต้อง )

ด้านหมายเหตุ: ฉันแน่ใจว่าคน DataBinding จะชอบ ViewBinding :)


ทำไมคุณไม่พูดอะไรเกี่ยวกับการใช้ตัวแปรในDataBinding? ฉันคิดว่ามันเป็นคุณสมบัติที่สำคัญในการหยุดใช้การอ้างอิงมุมมองเลย อย่างไรก็ตามคุณสามารถ "โยน" โมเดลการดูผ่าน<include ... />แท็กซึ่งเป็นข้อได้เปรียบที่ยิ่งใหญ่อีกประการหนึ่ง
Ircover

1
@Ircover คำถามเกี่ยวกับการรวมตัวกันของ KAE และ ViewBinding DataBinding ไม่ใช่ส่วนหนึ่งของคำถามนั้น
xinaiz

อ๊ะขอโทษ) ความเข้าใจผิดง่าย ๆ
Ircover

1
@BenLewis ถ้าการเชื่อมโยงของคุณถูกกำหนดเป็นล่าช้าคุณยังคงมีปัญหาเดียวกัน นั่นหมายความว่าไม่มีการวัดว่าคุณใช้ KAE หรือ ViewBinding อย่างไรคุณต้องปฏิบัติตามกฎที่เข้มงวดเมื่อเขียนโค้ดในส่วน
Flavio

1
"การใช้การเปลี่ยนแปลงโครงร่าง" - เมื่อใช้ ViewBinding คุณไม่จำเป็นต้องสร้างโครงการของคุณหลังจากเพิ่มมุมมองใหม่ด้วย ID คุณสามารถทำได้ทันที "binding.myTextView .. "
Tayyab Mazhar

19

ViewBindingkotlinx.android.syntheticแก้ไขปัญหาที่ใหญ่ที่สุดของ ในการsyntheticผูกหากคุณตั้งค่ามุมมองเนื้อหาของคุณเป็นเค้าโครงแล้วพิมพ์ id ที่มีอยู่ในเค้าโครงที่แตกต่างกันเท่านั้น IDE ช่วยให้คุณเติมข้อความอัตโนมัติและเพิ่มคำสั่งการนำเข้าใหม่ นอกจากว่านักพัฒนาจะตรวจสอบเป็นพิเศษเพื่อให้แน่ใจว่างบการนำเข้าของพวกเขาเพียงนำเข้ามุมมองที่ถูกต้องไม่มีวิธีที่ปลอดภัยในการตรวจสอบว่าสิ่งนี้จะไม่ทำให้เกิดปัญหารันไทม์ แต่ในที่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 เพื่อขยายมุมมองแล้วอ้างอิงฟิลด์ที่กำหนดผ่านตัวแปร
NapoleonTheCake

4
ดูเหมือนจะไม่เกิดขึ้นจริงในสถานการณ์ชีวิตจริง
Bencri

1
ตัวอย่างไม่สมเหตุสมผล คุณใช้มันไม่ถูกต้อง ทำไมคุณต้องนำเข้าสิ่งที่ไม่ถูกต้อง (activity_other) ทุกเฟรมเวิร์กที่คุณใช้ไม่ถูกต้องอาจทำให้เกิดปัญหาได้
นักพัฒนา android

2

kotlinx.android.synthetic ไม่ได้เป็นวิธีปฏิบัติที่แนะนำอีกต่อไปกล่าวโดย Google ในหนึ่งกระทำข้อความ "หนึ่งใน Reddit ด้าย

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

Syntheticsไม่ได้พัฒนาโดย google เป็นส่วนหนึ่งของส่วนขยาย kotlin android ที่สร้างขึ้นโดย JetBrains และผู้พัฒนา Google Android ค่อย ๆ เริ่มแทนที่ Synthetics ด้วย ViewBindins ในตัวอย่างและซอร์สโค้ด

"ตอนนี้คำถามมาซึ่งเราต้องพิจารณาด้วย

อ้างอิงจาก google (ดูการโยง, ButterKnife, Kotlin synthetics) ไลบรารี่เหล่านี้ถูกใช้อย่างประสบความสำเร็จโดยแอพจำนวนมากและแก้ปัญหาเดียวกัน

แต่สำหรับแอพส่วนใหญ่ google ขอแนะนำให้ลองใช้การโยงดูแทนไลบรารีเหล่านี้เนื่องจากการเชื่อมการดูจะช่วยให้การค้นหามุมมองที่ปลอดภัยและกระชับยิ่งขึ้น

รูปภาพอ้างอิงที่แนบมาเพื่อล้างสิ่งต่าง ๆ ได้อย่างรวดเร็ว ป้อนคำอธิบายรูปภาพที่นี่

อย่างไรก็ตามหากคุณต้องการไปที่แผนกคุณสามารถไปที่ลิงค์ด้านล่างนี้ https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc


2
1. ปลอดภัยเสมอ null - การดูการเชื่อมโยงจะยังคงมีปัญหาถ้าใช้ก่อนเงินเฟ้อหรือหลังวงจรชีวิตของการดูสิ้นสุด - ไม่มีความแตกต่างจากการสังเคราะห์ - ควรเป็นสีแดงสำหรับ ViewBinding 2. อ้างอิง id จากโครงร่างปัจจุบันเท่านั้น - จริง แต่ IDE ชี้ให้เห็นว่าคุณต้องการนำเข้ารหัสที่ได้รับจากเค้าโครงใดดังนั้นจึงไม่ใช่ปัญหาใหญ่ 3. รองรับ Kotlin & Java - อาร์กิวเมนต์ไม่ดีถ้าคุณสามารถใช้ Kotlin ในการพัฒนา android ได้แล้วทำไมต้องใช้ Java 4. จำนวนรหัสที่ต้องการ - การสังเคราะห์ Kotlin มีจำนวนต่ำสุดควรต่ำมากในตาราง
xinaiz

@xinaiz เหตุใดคุณจึงใช้งานก่อนที่จะขยายออกไปให้ทำตามวิธีการที่ถูกต้องในการใช้งานมิฉะนั้นคุณจะต้องเผชิญกับปัญหา คุณเคยไปที่ลิงค์ก่อนที่จะลงคะแนนและโพสต์ความคิดเห็น medium.com/androiddevelopers/ …
SourabhTech

ใช่ฉันเคยอ่านมาแล้ว ฉันไม่ได้ใช้มันก่อนสูบลมฉันแค่บอกว่าเป็นไปได้ "วิธีที่ถูกต้อง" หมายความว่ามีความเสี่ยงใช่มั้ย นอกจากนี้คุณข้ามor after view lifecycle endsส่วน?
xinaiz

@xinaiz 2. แต่มีโอกาสที่จะใช้รหัสผิดถ้าโครงการใหญ่กว่าและใช้ชื่อทรัพยากรเดียวกันหากนักพัฒนาหลายคนกำลังทำงานในโครงการ 3. มีความต้องการโครงการที่คุณต้องใช้ java และ kotlin ทั้งคู่ (หากโครงการได้รับการพัฒนาใน java แล้วและเริ่มต้นการเชื่อมโยงกับ kotlin แน่นอนว่ามันจะช่วยได้) 4. สำหรับซินธิติกคุณต้องนำเข้าห้องสมุดแยกต่างหาก มันมีอยู่แล้วใน Gradle ดังนั้นเห็นได้ชัดว่ามันใช้รหัสน้อย
SourabhTech

1
ในการตอบสนองต่อ 4. ห้องสมุดอะไร? มันเปิดใช้งานโดยค่าเริ่มต้น มันเป็นเรื่องการโต้แย้งเกี่ยวกับVSapply plugin: 'kotlin-android-extensions' viewBinding { enabled = true }ไม่แตกต่างกันมาก
xinaiz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.