When I first started using the Kotlin-Android-Extensions plug-in, I found it very comfortable. Instead of writing a cumbersome findViewByid method or introducing a ButterKnife reflection generated View, you can directly manipulate the ID resources of the XML layout file, greatly reducing template code and creating a good coding experience.

However, Google has recently started recommending that developers use ViewBinding instead of using kotlin-Android-Extensions. So today we’ll take a look at the underlying implementation of the Kotlin-Android-Extensions.

1. Write an XML layout file

<? The XML version = "1.0" encoding = "utf-8"? > <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">  <ImageView android:id="@+id/imageView" android:layout_width="30dp" android:layout_height="30dp" android:layout_centerInParent="true" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/imageView" android:layout_centerHorizontal="true" android:layout_marginTop="20dp" android:textSize="18sp" tools:text="Hello World" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView" Android :layout_centerHorizontal="true" Android :layout_marginTop="20dp" Android :text=" confirm "/> </RelativeLayout>Copy the code

Use the Kotlin-Android-extensions to manipulate the View Id of the XML directly

import kotlinx.android.synthetic.main.testactivity.*

/**
 * Create by wsg on 2021/1/27.
 */
class TestActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.testactivity)

        initView()
    }

    private fun initView() {
        imageView.setImageResource(R.drawable.about_pressed)
        textView.text = "Hello World"
        button.setOnClickListener {
            Log.d("TestActivity", "button clicked")
        }
    }
}
Copy the code

3. Use the Android Studio Tools -> Kotlin -> Show Kotlin Bytecode to view the TestActivity Bytecode file

The bytecode files are as follows

public final class TestActivity extends BaseActivity { private HashMap _$_findViewCache; protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(1300096); this.initView(); } private final void initView() { ((ImageView)this._$_findCachedViewById(id.imageView)).setImageResource(700248); TextView var10000 = (TextView)this._$_findCachedViewById(id.textView); Intrinsics.checkExpressionValueIsNotNull(var10000, "textView"); var10000.setText((CharSequence)"Hello World"); ((Button)this._$_findCachedViewById(id.button)).setOnClickListener((OnClickListener)null.INSTANCE); } public View _$_findCachedViewById(int var1) { if (this._$_findViewCache == null) { this._$_findViewCache = new HashMap(); } View var2 = (View)this._$_findViewCache.get(var1); If (var2 == null) {var2 = this.findViewById(var1); this._$_findViewCache.put(var1, var2); } return var2; // If the View is not found in the cache, call findViewById to find the View and store it in the cache. } public void _$_clearFindViewByIdCache() { if (this._$_findViewCache ! = null) { this._$_findViewCache.clear(); // Clear cache}}}Copy the code

The Key is the View ID, the value is the View itself, and the View is still findViewById, and the View is cached inside the Kotlin-Android-Extensions extension. It can be read from the Map cache the next time it is used. That automatically does findViewById for us.