Introduction to DataBinding: Three Architectural patterns Common architectural patterns

  • MVC: It is not indicated throughout the Android development documentation

    • It was widely used in 2011 and 2012
    • Why MVC pattern

      • Determined by the engineering structure:

        • XML in RES /layout: View layer
        • The Activity in SRC is the control layer, so it is an MVC architecture
    • Disadvantages:

      • Activity(Control layer) : Too bloated

        • It’s supposed to just do control but also take on the View, the model
        • No single responsibility leads to high coupling, poor scalability, and messy management
  • MVP: Activity only does View layer, introduces P layer (Presenter)

    • Features:

      • Stratified clear
    • View->P->View:

      • Example:

        • As a login function, after the user clicks the button, the Activity submits the information to the P layer. The P layer calls the server to get the model data, and feeds the model data back to the View layer through the interface callback.
    • Disadvantages:

      • Interface hell: Any P layer model data returned to the View layer through the interface callback
  • MVVM: Activity: View layer; Replace P layer with VM layer (ViewModel layer) :

    • Performance details: (View layer) The Activity accesses the VM layer (ViewModel implementation). The VM layer accesses the repository to retrieve model data. How does this data feed back to the View layer: using DataBinding

    • Reference DataBinding to implement bidirectional binding between the V layer and the VM layer

      • These are two one-way paths: clicking on the V layer triggers the VM layer; Modifying the VM layer affects the V layer
    • Detail 1: DataBinding on MVVM?

      • DataBinding is a toolset, independent of the schema (each schema can use DataBinding);
      • But for the most part, MVVM uses DataBinding; MVPS can also use DataBinding in a few cases; But MVC basically doesn’t
      • DataBinding predates MVVM
    • Detail 2: The ViewModel in the JetPack component library and the VM layer in MVVM are two different things

      • The VM layer in the MVVM architectural pattern is not the same as the ViewModel in the JetPack component library, but it is better to say that the VM layer implements the ViewModel component library, or not
      • The former is a component library, which is a toolset.
      • The latter is one of the architectures
    • Detail 3: Which design mode is best?

      • There is no best, only suitable;

      • MVC: Suitable for small projects, one or two people, split in the Activity, can handle well on the line

      • MVP: Project is too big (e.g. 8 minutes to compile), needs very clear layering (too many people developing)

      • MVVM: Frequently updated interface (NetEase Cloud Music, Tencent Video)

        • Data-driven development can be enabled with DataBinding+ViewModel+LiveData+LifeCycle
    • Detail 4: MVI architecture pattern

The DataBinding_Java version implements a data-driven UI

  • Design result: Implement a data-driven UI

    • Layer:

      • The Activity acts as the control layer
      • Javabeans as the Model layer
      • The layout file serves as the View layer
    • Implementation effect: In the Activity to open the JavaBean property modification, while the interface update

  • Environment preparation: Turn on the dataBinding switch

    • Gradle technology

      • The first opening method:

        DataBinding {enabled true}Copy the code
      • The second way to open:

        // The second way, go directly to the property databinding.enabled =trueCopy the code
  • Engineering structure:

  • Write the Model layer (JavaBean) : The User class (you will use LiveData for processing later, so you don’t need to write this)

    • Inheriting from the BaseObservable class: this class has DataBinding capabilities

        public class User extends BaseObservable
      Copy the code
    • Write the field: update this later

        private String name;
        private String pwd;
      Copy the code
    • Add the corresponding get: @bindable (will generate the corresponding numeric marker for the field)

       @Bindable
           public String getName() {
               return name;
           }
       ​
       @Bindable
           public String getPwd() {
               return pwd;
               notifyPropertyChanged(BR.pwd);
           }
      Copy the code
    • Add: notifyPropertyChanged(BR) to the set method. Specific attributes)

      public void setName(String name) { this.name = name; notifyPropertyChanged(BR.name); } public void setPwd(String PWD) {this. PWD = PWD; notifyPropertyChanged(BR.pwd); }Copy the code
      • The BR file is automatically generated (but not available until it is compiled)
      • APT technology: bytecode staking

      The br.name, name attribute will report an error because it is not specified in the data tag, which will be resolved below

    • Full code: User

      package com.wasbry.myapplication; import androidx.databinding.BaseObservable; import androidx.databinding.Bindable; public class User extends BaseObservable { private String name; private String pwd; public User(String name, String pwd) { this.name = name; this.pwd = pwd; } @Bindable public String getName() { return name; } public void setName(String name) { this.name = name; notifyPropertyChanged(BR.name); } @bindable public String getPwd() {return PWD; } public void setPwd(String pwd) { this.pwd = pwd; notifyPropertyChanged(BR.pwd); }}Copy the code
  • Manage the layout with DataBinding:

    • Introduce the DataBinding administrative layout:

      • When not introduced in DataBinding: VIew layer (Activity to process XML layout file),
      • Use DataBInding as an intermediate layer between your Activity and XML
    • Using DataBinding: Manage the controls in the layout

      • Use: Hover over the outermost TAB of the activity_main.xml file and click on the first prompt

      • When clicked: Split the original layout (activity_main.xml into two parts)

  • DataBinding layout split details: Manages all the controls in the layout

    • Layering: DataBinding manages the entire layout file, but splits it into two parts

      • Bring it to DataBinding for internal use: this is the data tag

         <layout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto"
             xmlns:tools="http://schemas.android.com/tools">
         ​
             <data>
         ​
             </data>
        Copy the code
      • Bring it to Android for View rendering

         <androidx.constraintlayout.widget.ConstraintLayout
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 tools:context=".MainActivity">
         ​
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text="Hello World!"
                     app:layout_constraintBottom_toBottomOf="parent"
                     app:layout_constraintLeft_toLeftOf="parent"
                     app:layout_constraintRight_toRightOf="parent"
                     app:layout_constraintTop_toTopOf="parent" />
         ​
             </androidx.constraintlayout.widget.ConstraintLayout>
        Copy the code
    • Hierarchical storage for location:

      • Above: submit a DataBinding for internal use

        • Implementation details: In this detached layout file, tag attributes are added

           <Target tag="layout/activity_main_0"
          Copy the code
        • Path: app/build/intermediates/data_binding_layout_info_type_merge/debug/out activity_main – layout. In the XML
        <? The XML version = "1.0" encoding = "utf-8" standalone = "yes"? > <Layout directory="layout" filePath="app\src\main\res\layout\activity_main.xml" isBindingData="true" isMerge="false" layout="activity_main" modulePackage="com.wasbry.myapplication" rootNodeType="androidx.constraintlayout.widget.ConstraintLayout"> <Targets> <Target tag="layout/activity_main_0" view="androidx.constraintlayout.widget.ConstraintLayout"> <Expressions /> <location endLine="26" endOffset="55" startLine="12" startOffset="4" /> </Target> </Targets> </Layout>Copy the code
      • The following section: bring it to Android for View rendering

        • Details: DataBinding adds a tag attribute to each layout file

            android:tag="layout/activity_main_0"
          Copy the code

          The tag attributes of the two layout files are the same. The top section uses the tag to find the bottom section

        • Path: app/build/intermediates/incremental/mergeDeBugResources/strpped activity_main in dir/layout. The XML
        <? The XML version = "1.0" encoding = "utf-8"? > <! DataBinding manages the entire layout file, but splits it into two parts --> <! -- For internal use in DataBinding --> <! - to View map using Android do - > < androidx. Constraintlayout. Widget. Constraintlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:tag="layout/activity_main_0" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>Copy the code
  • Map the layout file inside the DataBinding: add something to the data tag in the previous section

         <data>
             <variable
                 name="user"
                 type="com.wasbry.myapplication.User"
                 />
         </data>
    Copy the code

    Br. name in the JavaBean will not return an error

    • Two-way binding is now implemented:

      • DataBinding points to the Model layer (JavaBean) because the data tag is already specified internally

      • DataBinding points to the View layer:

        • The View layer is the layout file in layout, which is managed by DataBinding
    • Details: Although the full class name is used in type, this is not a reflection

  • Modify the following section in the layout file: Implement the View layer to Model layer binding

    • Core code:

       android:text="@{user.name}"
      Copy the code
    • Complete code:

      <! <LinearLayout Android :layout_width="match_parent" Android :layout_height="match_parent" Android :layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tv1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.name}" android:textSize="50sp" /> <TextView android:id="@+id/tv2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.pwd}" android:textSize="50sp"/> </LinearLayout>Copy the code
  • Modify control layer code: implement Model layer –>View layer always binding

    • SetContentView (r.layout.activity_main)

      • Use ActivityMainBinding to refer to the layout file:

         final ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        Copy the code
        • Proof refers to: click on it (CTRL+H left mouse button), found directly will draw the layout file automatically selected

      • Discard the setContentView statement

         //        setContentView(R.layout.activity_main);
        Copy the code
        • It’s actually called internally

    • Simulate Model data: Assume json data from the network, parsed into Javabeans

      • Schematic diagram:

      • Why does binding have a set function?

        binding.setUser(user); // The MainActivity layer is bound to the Model layer, and the View layer is bound to the Model layer before binding. At this point, the DataBinding is implemented as an intermediary for bidirectional binding between the View layer and the Model layerCopy the code

        Because user is specified in the name attribute inside the data tag; What does the name attribute specify, and DataBinding relies internally on APT annotation processor technology to generate a set method when scanning a layout file

        < data > < variable name = "user" / / this is the type = "com. Wasbry. Myapplication. User" / > < / data >Copy the code
    • Real machine test a wave:

  • Use threads to automatically trigger JavaBean property updates for data-driven UI effects

    • Bidirectional binding:

      • Model—>view

        binding.setUser(user); // Create a binding relationship with DataBinding, otherwise there is no effectCopy the code
      • View—>Model

         android:text="@{user.name}"
        Copy the code
    • What threads do: Modify Model layer (Javabeans) data

      //Model--->View new Thread(new Runnable() { @Override public void run() { for(int i = 0; i < 10; i++){ try { Thread.sleep(1000); User.setname (" + I +"); User.setpwd (" + I +"); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start();Copy the code
    • Real test: It’s actually done

  • Conclusion:

    • Lessons learned:

      • When using DataBinding, more than 90% of errors are reported because the layout file was written incorrectly

      • [bug Mc-10894] – Android Studio is a problem when the layout is checked (reboot can fix it)

        Click on it, reload it all, and you’re done

    • Android Studio shortcuts: When viewing the source code, the line is very long, so you need to format the code

      • Formatting code: CTRL+ALT+L(need to exit PC QQ), otherwise it will lead to conflict
    • DataBinding can be difficult to use: the larger the project, the more difficult it becomes, causing performance problems

      • Phones are getting better and better, and software is getting bigger and bigger