preface

Looking back on the development of Android, we have experienced MVC, MVP, MVVM and other development modes, and different technologies and solutions have emerged in the process. Today, I will introduce the evolution of the Android development model through some practical cases.

The evolution of Android development mode will be felt from the following development mode cases


  • Traditional development model
  • DataBinding implementation MVVM
  • The ViewModel + LiveData simplify MVVM
  • Jetpack Compose

Effect of case

Traditional development model

In the past, Android development often required manually fetching elements, setting click events, modifying data, and then manually setting them.

Roughly implemented as

class Activity1: AppCompatActivity() {var number = 0
    val tvNumber by lazy { findViewById<TextView>(R.id.tv_number) }
    val btnIncrement by lazy { findViewById<Button>(R.id.btn_increment) }
    val btnReduction by lazy { findViewById<Button>(R.id.btn_reduction) }

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState) setContentView(R.layout.activity_test) tvNumber.text = number.toString() btnIncrement.setOnClickListener{ number++ tvNumber.text = number.toString() } btnReduction.setOnClickListener { number--  tvNumber.text = number.toString() } } }Copy the code

DataBinding implementation MVVM

With DataBinding we can bind an Observable to the view, and changes to the Observable will automatically refresh the page display. Simplified the development, the specific code implementation is as follows.

  • Activity
class Activity1: AppCompatActivity() {private val number = ObservableInt(0)
    private val viewBinding by lazy {
        DataBindingUtil.inflate<ActivityTestBinding>(layoutInflater,R.layout.activity_test,null.false)}override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState) setContentView(viewBinding.root) viewBinding? .number = number viewBinding? .event = Event() } innerclass Event{

        fun increment(view: View){
            number.set(number.get() +1)}fun reduction(view: View){
            number.set(number.get(a)- 1)}}}Copy the code
  • xml
    <layout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="number"
            type="androidx.databinding.ObservableInt" />
        <variable
            name="event"
            type="com.example.demo.ui.Activity1.Event" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <TextView
            android:id="@+id/tv_number"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:text="@{String.valueOf(number)}"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.373" />

        <Button
            android:id="@+id/btn_reduction"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="-"
            android:onClick="@{event::reduction}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.315"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.516" />

        <Button
            android:id="@+id/btn_increment"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="+"
            android:onClick="@{event::increment}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.712"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.516" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Copy the code

Simplify MVVM with ViewModel+LiveData

ViewModel and LiveData as Jetpack architectural components further simplify Android development. LiveData can listen to data without having to deal with the life cycle and without the risk of memory leaks. The ViewModel makes it easier to store and manage user-interface data. Using ViewModel+LiveData in conjunction with the previous DataBinding component further simplifies MVVM pattern development.

  • Activity
class Activity1: AppCompatActivity() {private val viewBinding by lazy {
        DataBindingUtil.inflate<ActivityTestBinding>(layoutInflater,R.layout.activity_test,null.false)}override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState) setContentView(viewBinding.root) viewBinding? .vm = ViewModelProvider(this).get(NumberViewModel::class.java)viewBinding? .lifecycleOwner =this}}Copy the code
  • xml
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="vm"
            type="com.example.demo.vm.NumberViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <TextView
            android:id="@+id/tv_number"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:text="@{String.valueOf(vm.number)}"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.373" />

        <Button
            android:id="@+id/btn_reduction"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="-"
            android:onClick="@{()->vm.reduction()}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.315"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.516" />

        <Button
            android:id="@+id/btn_increment"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="+"
            android:onClick="@{()->vm.increment()}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.712"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.516" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Copy the code
  • ViewModel
class NumberViewModel: ViewModel() {val number by lazy {
        MutableLiveData<Int>().apply {
            value = 0}}fun increment(a){ number.value = number.value? .plus(1)}fun reduction(a){ number.value = number.value? .minus(1)}}Copy the code

Jetpack Compose

Google announced its new Android UI builder, Jetpack Compose, at IO 2019. Jetpack Compose uses much less code for its layout and is built with a declarative UI similar to Flutter and SwiftUI. Further simplifies Android development.

  • Activity
class Activity1 : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?). {
    super.onCreate(savedInstanceState)
    setContent {
      home()
    }
  }

  @Composable
  fun home(a){
    val model = NumberModel()
    MaterialTheme {
      Center {
        FlowColumn(
          crossAxisAlignment = FlowCrossAxisAlignment.Center
        ) {
          Text(
            text = "${model.number}",
            style = TextStyle(
              fontSize = Sp(15F),
              fontWeight = FontWeight.Bold
            )
          )
          FlowRow {
            Container(padding = EdgeInsets(10.dp)) {
              Button(onClick = {
                model.reduction()
              }) {
                Text(text = "-")
              }
            }
            Container(padding = EdgeInsets(10.dp)) {
              Button(onClick = {
                model.increment()
              }) {
                Text(text = "+")}}}}}}}}Copy the code
  • Model
@Model
class NumberModel {

  var number = 0

  fun increment(a){
    number++
  }

  fun reduction(a){
    number--
  }

}
Copy the code
  • Jetpack Compose implements the effect

conclusion

Today through a simple case, explained the specific implementation of a variety of Android development mode, experience the evolution of Android development mode. Later, I will bring you more in-depth case explanation.