MVP Mode Actual Warfare (Music APP-Android-Kotlin)

1. What is that?

MVP is a design pattern (framework), because its excellent decoupling function is widely used in Android project. It divides the application into Model-View-Presenter, which is called MVP for short.

  • Model is responsible for data processing and storage, and callback data to Presenter
  • Presenter is responsible for forwarding View layer requests (such as clicking, updating view data) to the corresponding Model, receiving callbacks and notifying the View layer to update the view.
  • View (View) is only responsible for displaying data
  • Contract (contract class) is only used to define the interface between View and Model for easy management and viewing.

The basic process of a simple view update

The order is according to (1), (3) and (4)
In View, we send a request to Presenter to update TextView.
2 Presenter receives the request and sends the request for String to the corresponding Model (it may take time to operate in the middle, so it may need a callback interface)
3. Successfully get the data and then send it to Presenter through the callback interface.
4 Presenter gets the data and triggers the View callback
5 Finally complete the view update of View.
From beginning to end, View only processes the user's request (updating TextView) and sends it to Presenter, then provides a callback for updating the view; Presenter only does forwarding, but does not process logic itself; model is responsible for providing information, including data processing.

Some versions of MVP may choose to put data processing into Presenter, and then the model has only one setter/getter function similar to JavaBean, but I think this process makes Presenter bloated, so I choose to put logical processing into Model. Either way can.

2. MVP Universal Framework

2.1 Control Layer
Contract doesn't have a very general framework, because each view and each model works differently. Here's an example from the figure above.

class DetailContract{
    interface DetailView{
        fun onChangeText(String)
    }

    interface DetailModel {
        fun getNowText(callBack: GetTextCallBack)
    }
    interface GetTextCallBack{
        fun onSuccess(str:String)
        fun onFail(info:String)
    }
}

2.2 Model level
Model also has no very general framework. Here's an example from the figure above.

class SampleModel: DetailContract.DetailModel{
    override getNowText(callBack: GetTextCallBack){
        val str = ...
        //These are the operations to get String
        if(str!=""){
            callBack.onSuccess(str)   
        }else{
            callBake.onFail("Acquisition failure")
        }
    }
}

The concrete Model class here implements the interface in the Contract contract class to facilitate our Presenter calls.
2.3 View level
View in Android generally includes two kinds, one is Activity, the other is Fragment, which only gives the encapsulation of Activity. Fragment is similar and needs to deal with some life cycle problems.

Activity:

abstract class BaseActivity<V,T:BasePresenter<V>>:Activity(){

    val TAG:String = javaClass.simpleName

    protected lateinit var mPresenter: T

    lateinit var mContext: Context

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mContext = this
        //Initialize Presenter
        mPresenter = createPresenter()
        //Binding Presenter and View
        mPresenter.attachView(this as V)
        //Initialize layout
        initView(savedInstanceState)
    }

    /**
     * The method of initializing view that should be implemented by subclasses
     */
    abstract fun initView(savedInstanceState: Bundle?)

    /**
     * Create the corresponding Presenter
     */
    abstract fun createPresenter():T

    //Unbind
    override fun onDestroy() {
        super.onDestroy()
        mPresenter.detachView()
    }
}

Base Activity is an abstract class, which should be inherited by all activities that join the MVP pattern. Generic V represents the view (i.e. itself), and T is the corresponding Presenter. The View layer holds references to the corresponding Presenter for sending messages.
2.4 Presenter layer

abstract class BasePresenter<T> {
    //Weak references to the View interface type prevent the view held from being destroyed, but the presenter still holds, resulting in memory leaks
    protected lateinit var mViewRef:Reference<T>

    //Binding View Reference
    fun attachView(view:T){
        mViewRef = SoftReference<T>(view)
    }

    //Get the View reference for the current binding
    protected fun getView(): T? {
        return mViewRef.get()
    }

    //Is View Binded
    fun isViewAttached(): Boolean {
        return mViewRef != null&&mViewRef.get()!=null
    }

    //Remove references
    fun detachView(){
        if (mViewRef != null){
            mViewRef.clear()
        }
    }
}

BasePresenter is an abstract class that should be inherited by all Presenters that join the MVP pattern.
Presenter holds a weak reference in the View layer, and includes four methods related to weak reference. They are binding the reference of View, getting the reference of the current View, deciding whether the View has been bound and removing the reference of View.
There is also a corresponding Model object in the specific Presenter. Presenter holds both View and Model so that it can forward information.

The input is the View interface type in Control because Presenter can only transmit information to view through the interface. Not a specific type.

These are some commonly used frameworks. Let's continue to deepen our understanding with real combat.

3. actual combat

This example is selected from the mid-term assessment of Hongyan Mobile Development Department, which is about a music App. Just analyze the playback page (because I made two pages)

Keywords: Android Fragment Mobile

Added by Brad420 on Wed, 29 May 2019 12:53:37 +0300