6、改造MVP--让数据容器也能感知View生命周期变化

6、改造MVP--让数据容器也能感知View生命周期变化,第1张

ILifecycleOwner接口:提供getLifecycleProvider(): LifecycleProvider,实现该接口可通过getLifecycleProvider()方法获取LifecycleProvider对象
package com.example.jetpackbysob.musiclisttestfinal.lifecycle

/**
 * Project_name:JetPackBySob
 * Created by:ChenFuXu.
 * Date: 2022/5/2 22:24
 */
interface ILifecycleOwner {
    /**
     * 获取LifecycleProvider
     */
    fun getLifecycleProvider(): LifecycleProvider
}

BaseActivity:  持有mLifecycleProvider对象,同时实现了ILifecycleOwner接口,BaseActivity子类可通过getLifecycleProvider方法获取LifecycleProvider对象

BaseActivity 

package com.example.jetpackbysob.musiclisttestfinal.base

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.jetpackbysob.musiclisttestfinal.lifecycle.ILifecycleOwner
import com.example.jetpackbysob.musiclisttestfinal.lifecycle.LifeState
import com.example.jetpackbysob.musiclisttestfinal.lifecycle.LifecycleProvider

/**
 * Project_name:JetPackBySob
 * Created by:ChenFuXu.
 * Date: 2022/5/2 17:25
 *
 */
open class BaseActivity : AppCompatActivity(), ILifecycleOwner {
    private val mLifecycleProvider by lazy {
        LifecycleProvider()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mLifecycleProvider.makeLifeState(LifeState.ON_CREATE)
    }

    override fun onStart() {
        super.onStart()
        mLifecycleProvider.makeLifeState(LifeState.ON_START)

    }

    override fun onResume() {
        super.onResume()
        mLifecycleProvider.makeLifeState(LifeState.ON_RESUME)
    }

    override fun onPause() {
        super.onPause()
        mLifecycleProvider.makeLifeState(LifeState.ON_PAUSE)
    }

    override fun onStop() {
        super.onStop()
        mLifecycleProvider.makeLifeState(LifeState.ON_STOP)
    }

    override fun onDestroy() {
        super.onDestroy()
        mLifecycleProvider.makeLifeState(LifeState.ON_DESTROY)
    }

    override fun getLifecycleProvider(): LifecycleProvider {
        return mLifecycleProvider
    }
}

LifecycleProvider: 管理注册进来的接口:ILifecycle,保存当前生命周期状态,需要监听就保存到mLifecycleListeners集合中,在MusicPresenter(P层)通过mOwner?.getLifecycleProvider()?.addLifecycle(mViewLifeImpl)方法添加到集合中mLifecycleProvider.makeLifeState -- 设置不同的生命周期状态

package com.example.jetpackbysob.musiclisttestfinal.lifecycle

import android.util.Log

/**
 * Project_name:JetPackBySob
 * Created by:ChenFuXu.
 * Date: 2022/5/2 20:42
 *
 * 这个类的职责是管理注册进来的接口:ILifecycle
 * 保存当前的生命周期状态
 */
class LifecycleProvider {
    companion object {
        private const val TAG = "LifecycleProvider"
    }

    private val mLifecycleListeners = arrayListOf()
    // 当前的生命周期状态
    var mCurrentLifeState: LifeState = LifeState.ON_DESTROY

    /**
     * 添加Lifecycle
     */
    fun addLifecycle(lifecycleListener: AbsLifecycle) {
        if (!mLifecycleListeners.contains(lifecycleListener)) {
            mLifecycleListeners.add(lifecycleListener)
        }
    }

    /**
     * 移除Lifecycle
     */
    fun removeLifecycle(lifecycleListener: AbsLifecycle) {
        mLifecycleListeners.remove(lifecycleListener)
    }

    /**
     * 改变生命周期的状态
     */
    fun makeLifeState(state: LifeState) {
        mCurrentLifeState = state
        mLifecycleListeners.forEach {
            it.onViewLifeStateChange(state)
        }
        when (state) {
            LifeState.ON_CREATE -> {
                handlerCreateState()
            }
            LifeState.ON_START -> {
                handlerStartState()
            }
            LifeState.ON_RESUME -> {
                handlerResumeState()
            }
            LifeState.ON_PAUSE -> {
                handlerPauseState()
            }
            LifeState.ON_STOP -> {
                handlerStopState()
            }
            LifeState.ON_DESTROY -> {
                handlerDestroyState()
            }
        }
    }

    private fun handlerDestroyState() {
        mLifecycleListeners.forEach {
            it.onDestroy()
        }
        // 清空所有数据
        mLifecycleListeners.clear()
    }

    private fun handlerStopState() {
        mLifecycleListeners.forEach {
            it.onStop()
        }
    }

    private fun handlerPauseState() {
        mLifecycleListeners.forEach {
            it.onPause()
        }
    }

    private fun handlerResumeState() {
        mLifecycleListeners.forEach {
            it.onResume()
        }
    }

    private fun handlerStartState() {
        mLifecycleListeners.forEach {
            it.onStart()
        }
    }

    private fun handlerCreateState() {
        mLifecycleListeners.forEach {
            it.onCreate()
        }
    }

    /**
     * 当当前的生命周期进行比较
     * 比当前生命周期级别高的才进行更新
     */
    fun isAtLeast(state: LifeState): Boolean {
        Log.d(TAG, "cfx isAtLeast mCurrentLifeState = $mCurrentLifeState state = $state")
        val isAtLeastState: Boolean = mCurrentLifeState > state
        Log.d(TAG, "cfx isAtLeast isAtLeastState = $isAtLeastState")
        return isAtLeastState
    }
}

V层:MusicActivity,继承BaseActivity,因此可以获取到LifecycleProvider对象,同时持有MusicPresenter对象,由于在MusicPresenter中需要用到LifecycleProvider的addLifecycle方法,所以在MusicActivity中初始化MusicPresenter.mOwner = this, 由于this继承了BaseActivity, 实现了ILifecycleOwner接口,所以在MusicPresenter中持有了mOwner对象,进而可以获取到LifecycleProvider

package com.example.jetpackbysob.musiclisttestfinal

import android.os.Bundle
import android.util.Log
import com.example.jetpackbysob.R
import com.example.jetpackbysob.musiclisttestfinal.base.BaseActivity
import kotlinx.android.synthetic.main.activity_music_list.*

/**
 * Project_name:JetPackBySob
 * Created by:ChenFuXu.
 * Date: 2022/5/1 12:50
 *
 * 让数据容器也能感知View生命周期的变化
 */
class MusicActivity : BaseActivity() {
    companion object {
        private const val TAG = "MusicActivity"
    }

    private val mMusicPresenter by lazy {
        MusicPresenter.instance
    }

    private val mPlayerPresenter by lazy {
        PlayerPresenter.instance
    }

    init {
        Log.d(TAG, "cfx MusicActivity init")
        MusicPresenter.mOwner = this
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_music_list)
        initDataListener()
        initViewListener()
    }


    override fun onDestroy() {
        super.onDestroy()
    }

    /**
     * 监听数据的变化
     */
    private fun initDataListener() {
        println("$TAG, cfx initDataListener Thread.currentThread().name = ${Thread.currentThread().name}")
        /**
         * 让数据容器也能感知View生命周期的变化
         * addListener添加形参owner
         */
        mMusicPresenter.mMusicList.addListener(this) {
            println("$TAG, cfx initDataListener Thread.currentThread().name = ${Thread.currentThread().name}")
            // 音乐列表数据变化
            println("$TAG, cfx initDataListener mMusicList.size = ${it?.size}")
            get_music_count.text = "共 ${it?.size} 首音乐"

        }
        mMusicPresenter.mLoadState.addListener(this) {
            // 播放状态的数据变化
            println("$TAG, cfx initDataListener mLoadState = $it")
        }
    }

    private fun initViewListener() {
        get_music_list.setOnClickListener {
            // 获取音乐列表
            mMusicPresenter.getMusicList()
        }
    }
}

P层:MusicPresenter

package com.example.jetpackbysob.musiclisttestfinal

import android.util.Log
import com.example.jetpackbysob.musiclisttestfinal.domain.MusicBean
import com.example.jetpackbysob.musiclisttestfinal.lifecycle.AbsLifecycle
import com.example.jetpackbysob.musiclisttestfinal.lifecycle.ILifecycleOwner
import com.example.jetpackbysob.musiclisttestfinal.lifecycle.LifeState

/**
 * Project_name:JetPackBySob
 * Created by:ChenFuXu.
 * Date: 2022/5/1 12:52
 */
class MusicPresenter() : AbsLifecycle() {
    companion object {
        private const val TAG = "MusicPresenter"

        val instance by lazy {
            MusicPresenter()
        }

        var mOwner : ILifecycleOwner? = null
    }

    enum class MusicLoadState {
        LOADING, EMPTY, SUCCESS, ERROR
    }

    private val mMusicModel by lazy {
        MusicModel()
    }

    private val mViewLifeImpl by lazy {
        ViewLifeImpl()
    }

    val mMusicList = DataListenerContainer>()
    val mLoadState = DataListenerContainer()

    private val page = 1
    private val size = 30

    init {
        Log.d(TAG, "cfx MusicPresenter init")
        mOwner?.getLifecycleProvider()?.addLifecycle(mViewLifeImpl)
        // mOwner?.getLifecycleProvider()?.addLifecycle(this)
    }

    inner class ViewLifeImpl : AbsLifecycle() {
        override fun onCreate() {
            Log.d(TAG, "cfx ViewLifeImpl onCreate")

        }

        override fun onStart() {
            Log.d(TAG, "cfx ViewLifeImpl onStart")

        }

        override fun onResume() {
            Log.d(TAG, "cfx ViewLifeImpl onResume")

        }

        override fun onPause() {
            Log.d(TAG, "cfx ViewLifeImpl onPause")

        }

        override fun onStop() {
            Log.d(TAG, "cfx ViewLifeImpl onStop")

        }

        override fun onDestroy() {
            Log.d(TAG, "cfx ViewLifeImpl onDestroy")

        }

        override fun onViewLifeStateChange(state: LifeState) {
            Log.d(TAG, "cfx ViewLifeImpl onViewLifeStateChange state = $state")
        }
    }

    /**
     * 获取音乐列表
     */
    fun getMusicList() {
        mLoadState.value = MusicLoadState.LOADING
        // 从model层获取音乐列表,这个 *** 作一般是异步 *** 作,子线程执行
        mMusicModel.loadMusicListByPage(page, size, object: MusicModel.OnMusicLoadResult {
            override fun onSuccess(result: List) {
                // 加载音乐列表成功
                mMusicList.value = result
                mLoadState.value = if (result.isEmpty()) {
                    MusicLoadState.EMPTY
                } else {
                    MusicLoadState.SUCCESS
                }
                println("$TAG getMusicList onSuccess 获取音乐列表成功")

            }

            override fun onError(msg: String, code: Int) {
                // 加载音乐列表失败
                mLoadState.value = MusicLoadState.ERROR
                println("$TAG getMusicList onError msg: $msg code: $code")
            }

        })
    }

    override fun onCreate() {
        Log.d(TAG, "cfx MusicPresenter onCreate")
    }

    override fun onStart() {
        Log.d(TAG, "cfx MusicPresenter onStart")
    }

    override fun onResume() {
        Log.d(TAG, "cfx MusicPresenter onResume")
    }

    override fun onPause() {
        Log.d(TAG, "cfx MusicPresenter onPause")
    }

    override fun onStop() {
        Log.d(TAG, "cfx MusicPresenter onStop")
    }

    override fun onDestroy() {
        Log.d(TAG, "cfx MusicPresenter onDestroy")
    }

    override fun onViewLifeStateChange(state: LifeState) {
        Log.d(TAG, "cfx MusicPresenter onViewLifeStateChange state = $state")
    }
}

 DataListenerContainer:监听数据的变化,通知UI更新,感知v层生命周期变化

package com.example.jetpackbysob.musiclisttestfinal

import android.os.Looper
import android.util.Log
import com.example.jetpackbysob.musiclisttestfinal.lifecycle.AbsLifecycle
import com.example.jetpackbysob.musiclisttestfinal.lifecycle.ILifecycleOwner
import com.example.jetpackbysob.musiclisttestfinal.lifecycle.LifeState
import com.example.jetpackbysob.musiclisttestfinal.lifecycle.LifecycleProvider

/**
 * Project_name:JetPackBySob
 * Created by:ChenFuXu.
 * Date: 2022/4/30 22:51
 *
 * 数据容器:监听数据的变化
 * 这个类中添加对数据进行监听的功能
 *
 * 增加功能:让数据容器也能感知View生命周期的变化
 */
class DataListenerContainer {
    companion object {
        private const val TAG = "DataListenerContainer"
    }

    /**
     * 该集合保存所有的匿名函数类型
     * 是对数据变化的观察者
     */
    private val mValueObservers = arrayListOf<(T?) -> Unit>()
    /**
     * 该集合为了每个添加的匿名函数与相应的LifecycleProvider对应
     */
    private val mViewLifecycleProviders = hashMapOf<(T?) -> Unit, LifecycleProvider>()

    // 数据
    var value: T? = null
        /**
         * 当设置数据时,即表明数据发生变化
         * 就进行通知更新
         */
        set(value: T?) {
            // 判断当前是否是主线程,如果是主线程,继续执行
            // 如果不是主线程,切换到主线程执行
            if (Looper.getMainLooper().thread == Thread.currentThread()) {
                mValueObservers.forEach {
                    dispatchValue(it, value)
                }
            } else {
                // 切换到主线程执行
                App.mHandler.post {
                    mValueObservers.forEach {
                        dispatchValue(it, value)
                    }
                }
            }
        }

    /**
     * 根据生命周期的状态进行通知
     */
    private fun dispatchValue(it: (T?) -> Unit, value: T?) {
        // 根据匿名函数,拿到对应的lifecycleProvider
        val lifecycleProvider: LifecycleProvider? = mViewLifecycleProviders[it]
        if (lifecycleProvider != null &&
            lifecycleProvider.isAtLeast(LifeState.ON_START)
        ) {
            Log.d(TAG, "cfx DataListenerContainer dispatchValue 数据更新")
            it.invoke(value)
        }
    }

    /**
     * 将owner和匿名函数添加到数据容器中去
     * 这里有可能有多个View进行监听
     * 而owner需要和block对应起来
     * 所以这里需要用集合管理起来
     */
    fun addListener(owner: ILifecycleOwner, valueObserver: (T?) -> Unit) {
        var lifecycleProvider = owner.getLifecycleProvider()
        mViewLifecycleProviders[valueObserver] = lifecycleProvider
        // 当View destroy 时需要从集合中删除
        val observerWrapper = ValueObserverWrapper(valueObserver)
        lifecycleProvider.addLifecycle(observerWrapper)
        if (!mValueObservers.contains(valueObserver)) {
            mValueObservers.add(valueObserver)
        }
    }

    /**
     * 该内部类是监听生命周期,因为是内部类,可以直接拿到mViewLifecycleProviders对象
     */
    inner class ValueObserverWrapper(private val valueObserver: (T?) -> Unit) : AbsLifecycle() {
        override fun onViewLifeStateChange(state: LifeState) {
            // 当监听到当前的view,生命周期为destroy的时候,就把LifecycleProvider从集合中删除
            if (state == LifeState.ON_DESTROY) {
                Log.d(TAG, "cfx ValueObserverWrapper onViewLifeStateChange state = $state 移除监听")
                mViewLifecycleProviders.remove(valueObserver)
            }
        }
    }
}

ILifeILiecyclerc

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/893338.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-14
下一篇 2022-05-14

发表评论

登录后才能评论

评论列表(0条)

保存