雙向綁定涉及兩個部分,即將業務狀態的變化傳遞給UI,以及將用戶輸入信息傳遞給業務模型。java
首先咱們來看業務狀態是如何傳遞給UI的。開啓dataBinding後,編譯器爲佈局activitymain.xml生成類ActivityMainBinding和它的實現類ActivityMainBindingImpl。抽象類ActivityMainBinding派生自ViewDataBinding,後者是BaseObserver的子類。ViewDataBinding有一個成員mChoreographer,它保存了主線程ActivityThread的Looper對象,業務狀態的變動就是經過消息發送給主線程的,接着主線程完成對UI的更新。咱們以一個例子來講明。對於下面的佈局:android
<?xml version="1.0" encoding="utf-8"?> <layout> <data> <variable name="text" type="java.lang.String"/> </data> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <EditText android:id="@+id/label" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@={text}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
當調用ActivityMainBinding.setText()時,執行的操做大體以下:app
ActivityMainBindingImpl.setText() ViewDataBinding.requestRebind() ViewDataBinding.mChoregrapher.postFrameCallback() some_native_code() Choregrapher.FrameDisplayEventReceiver.onVsync() Choregrapher.FrameDisplayEventReceiver.mHandler.sendMessage() ... Handler.dispatchMessage() Choregrapher.FrameDisplayEventReceiver.run() Choregrapher.doFrame() ViewDataBinding.executeBindings() TextViewBindingAdapter.setText() TestView.setText()
這裏有兩個地方要注意一下。首先,Choregrapher經過Looper.myLooper()獲得Looper對象,而myLooper()返回了一個線程本地對象,所以ViewDataBinding對象必須在主線程中建立。其次,Handler分派消息(Handler.dispatchMessage)的順序爲Message.callback,Handler.mCallback,Handler.handleMessage。這種分派方式提升了消息處理的靈活性。oop
如今來考察用戶輸入是如何傳遞給業務模型的。當用戶輸入數據時,EditText會將信息傳遞給TextWatcher。雙向綁定會自動創建TextWatcher對象,並註冊到EditText,這個TextWatcher包含一個InverseBindingListener對象,當用戶輸入時,信息沿着下面的路徑傳遞給ActivityMainBindingImpl對象。佈局
EditText TextWatcher InverseBindingListener ActivityMainBindingImpl
所以經過ActivityMainBindingImpl對象,咱們就能夠直接獲得用戶的輸入了。post