欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android如何使用Flow封裝一個FlowBus工具類

 更新時間:2024年09月24日 12:02:59   作者:淡淡的香煙  
本文介紹了如何在Android中使用Flow封裝一個FlowBus工具類,以替代EvenutBus、Rxbus、LiveDataBus、LiveData等第三方依賴包,作者提供了在Activity、Fragment、Service和Websock中使用FlowBus的具體代碼,并解釋了實現(xiàn)的效果,文章最后還提供了項目demo源碼的下載鏈接

Android中使用Flow封裝一個FlowBus工具類

? 做過Android的同學應該都使用過EvenutBus、Rxbus、LiveDataBus、LiveData等,這些第三方不僅要導入依賴包,而且還要注冊和取消注冊,使用起來非常麻煩,稍不注意就導致內(nèi)存泄漏,自從接觸了Flow、SharedFlow之后感覺使用起來方便多了,于是產(chǎn)生了一個封裝通用事件工具類的想法,直接上代碼.

1.FlowBus:

/**
 * @auth: njb
 * @date: 2024/7/18 10:17
 * @desc: 基于Flow封裝的FlowBus
 */
object FlowBus {
    private const val TAG = "FlowBus"
    private val busMap = mutableMapOf<String, FlowEventBus<*>>()
    private val busStickMap = mutableMapOf<String, FlowStickEventBus<*>>()
    @Synchronized
    fun <T> with(key: String): FlowEventBus<T> {
        var flowEventBus = busMap[key]
        if (flowEventBus == null) {
            flowEventBus = FlowEventBus<T>(key)
            busMap[key] = flowEventBus
        }
        return flowEventBus as FlowEventBus<T>
    }
    @Synchronized
    fun <T> withStick(key: String): FlowStickEventBus<T> {
        var stickEventBus = busStickMap[key]
        if (stickEventBus == null) {
            stickEventBus = FlowStickEventBus<T>(key)
            busStickMap[key] = stickEventBus
        }
        return stickEventBus as FlowStickEventBus<T>
    }
    open class FlowEventBus<T>(private val key: String) : DefaultLifecycleObserver {
        //私有對象用于發(fā)送消息
        private val _events: MutableSharedFlow<T> by lazy {
            obtainEvent()
        }
        //暴露的公有對象用于接收消息
        private val events = _events.asSharedFlow()
        open fun obtainEvent(): MutableSharedFlow<T> =
            MutableSharedFlow(0, 1, BufferOverflow.DROP_OLDEST)
        //在主線程中接收數(shù)據(jù)
        fun register(lifecycleOwner: LifecycleOwner,action: (t: T) -> Unit){
            lifecycleOwner.lifecycleScope.launch {
                events.collect {
                    try {
                        action(it)
                    }catch (e:Exception){
                        e.printStackTrace()
                        Log.e(TAG, "FlowBus - Error:$e")
                    }
                }
            }
        }
        //在協(xié)程中接收數(shù)據(jù)
        fun register(scope: CoroutineScope,action: (t: T) -> Unit){
            scope.launch {
                events.collect{
                    try {
                       action(it)
                    }catch (e:Exception){
                        e.printStackTrace()
                        Log.e(TAG, "FlowBus - Error:$e")
                    }
                }
            }
        }
        //在協(xié)程中發(fā)送數(shù)據(jù)
        suspend fun post(event: T){
            _events.emit(event)
        }
        //在主線程中發(fā)送數(shù)據(jù)
        fun post(scope: CoroutineScope,event: T){
            scope.launch {
                _events.emit(event)
            }
        }
        override fun onDestroy(owner: LifecycleOwner) {
            super.onDestroy(owner)
            Log.w(TAG, "FlowBus ==== 自動onDestroy")
            val subscriptCount = _events.subscriptionCount.value
            if (subscriptCount <= 0)
                busMap.remove(key)
        }
        // 手動調(diào)用的銷毀方法,用于Service、廣播等
        fun destroy() {
            Log.w(TAG, "FlowBus ==== 手動銷毀")
            val subscriptionCount = _events.subscriptionCount.value
            if (subscriptionCount <= 0) {
                busMap.remove(key)
            }
        }
    }
    class FlowStickEventBus<T>(key: String) : FlowEventBus<T>(key) {
        override fun obtainEvent(): MutableSharedFlow<T> =
            MutableSharedFlow(1, 1, BufferOverflow.DROP_OLDEST)
    }
}

2.在Activity中的使用:

2.1傳遞參數(shù)給主界面Activity:

/**
 * @auth: njb
 * @date: 2024/9/10 23:49
 * @desc: 描述
 */
class TestActivity :AppCompatActivity(){
    private val textView:TextView by lazy { findViewById(R.id.tv_test) }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)
        initFlowBus()
    }
    private fun initFlowBus() {
        val messageEvent = MessageEvent()
        messageEvent.message = "stop"
        messageEvent.state = false
        textView.setOnClickListener {
            lifecycleScope.launch {
                FlowBus.with<MessageEvent>("test").post(this, messageEvent)
                finish()
            }
        }
    }
}

2.2 MainActivity接收:

/**
 * 初始化
 */
private fun initView() {
    binding.rvWallpaper.apply {
        layoutManager = GridLayoutManager(this@MainActivity, 2)
        adapter = wallPaperAdapter
    }
    binding.btnGetWallpaper.setOnClickListener {
        lifecycleScope.launch {
            mainViewModel.mainIntentChannel.send(MainIntent.GetWallpaper)
        }
        val intent = Intent(this@MainActivity,TestActivity::class.java)
        startActivity(intent)
    }
    FlowBus.with<MessageEvent>("test").register(this@MainActivity) {
        LogUtils.d(TAG,it.toString())
        if(it.message == "stop"){
            LogUtils.d(TAG,"===接收到的消息為==="+it.message)
        }
    }
    FlowBus.with<MessageEvent>("mineFragment").register(this@MainActivity) {
        LogUtils.d(TAG,it.toString())
        if(it.message == "onMine"){
            LogUtils.d(TAG,"===接收到的消息為1111==="+it.message)
        }
    }
}

3.在Fragment中的使用:

3.1 發(fā)送數(shù)據(jù)

package com.cloud.flowbusdemo.fragment
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.cloud.flowbusdemo.databinding.FragmentMineBinding
import com.cloud.flowbusdemo.flow.FlowBus
import com.cloud.flowbusdemo.model.MessageEvent
import kotlinx.coroutines.launch
private const val ARG_PARAM_NAME = "name"
private const val ARG_PARAM_AGE = "age"
/**
 * @auth: njb
 * @date: 2024/9/17 19:43
 * @desc: 描述
 */
class MineFragment :Fragment(){
    private lateinit var binding: FragmentMineBinding
    private val TAG = "MineFragment"
    private var name: String? = null
    private var age: Int? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            name = it.getString(ARG_PARAM_NAME)
            age = it.getInt(ARG_PARAM_AGE)
        }
        Log.i(TAG, "MainFragment 傳遞到 MineFragment 的參數(shù)為 name = $name , age = $age")
        Log.d(TAG, "姓名:" + name + "年齡:" + age)
    }
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentMineBinding.inflate(layoutInflater)
        initView()
        return binding.root
    }
    private fun initView() {
        val messageEvent = MessageEvent()
        messageEvent.message = "onMine"
        messageEvent.state = false
        binding.let {
            it.tvTitle.text = name
            it.tvAge.text  = age.toString()
            it.tvTitle.setOnClickListener {
                lifecycleScope.launch {
                    FlowBus.with<MessageEvent>("mineFragment").post(this, messageEvent)
                }
            }
        }
    }
}

3.2 接收數(shù)據(jù):

private fun initView() {
    binding.rvWallpaper.apply {
        layoutManager = GridLayoutManager(this@MainActivity, 2)
        adapter = wallPaperAdapter
    }
    binding.btnGetWallpaper.setOnClickListener {
        lifecycleScope.launch {
            mainViewModel.mainIntentChannel.send(MainIntent.GetWallpaper)
        }
        val intent = Intent(this@MainActivity,TestActivity::class.java)
        startActivity(intent)
    }
    FlowBus.with<MessageEvent>("test").register(this@MainActivity) {
        LogUtils.d(TAG,it.toString())
        if(it.message == "stop"){
            LogUtils.d(TAG,"===接收到的消息為==="+it.message)
        }
    }
    FlowBus.with<MessageEvent>("mineFragment").register(this@MainActivity) {
        LogUtils.d(TAG,it.toString())
        if(it.message == "onMine"){
            LogUtils.d(TAG,"===接收到的消息為1111==="+it.message)
        }
    }
}

4.在Service中的使用:

4.1發(fā)送數(shù)據(jù):

private fun initService() {
    val intent = Intent(this@MainActivity, FlowBusTestService::class.java)
    intent.putExtra("sockUrl","")
    startService(intent)
}

4.2接收數(shù)據(jù):

/**
 * @auth: njb
 * @date: 2024/9/22 23:32
 * @desc: 描述
 */
class FlowBusTestService:Service() {
    private var sock5Url:String ?= null
    private val TAG = "FlowBusTestService"
    override fun onBind(intent: Intent?): IBinder? {
        return null
    }
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        intent?.let {
            this.sock5Url = intent.getStringExtra("sockUrl")
            LogUtils.d(TAG,"====收到的ip為==="+this.sock5Url)
        }
        return if (intent?.action == Constants.ACTION_DISCONNECT) {
            disconnect()
            START_NOT_STICKY
        } else {
            connect()
            START_STICKY
        }
    }
    private fun connect() {
    }
    private fun disconnect() {
    }
}

5.在Websock中的使用:

5.1發(fā)送數(shù)據(jù):

private fun connectWebSocket() {
    LogUtils.e(TAG, "===connectUrl===$currentWebSocketUrl")
    try {
        if (mWebSocketManager == null) {
            return
        }
        mWebSocketManager?.addListener(object : SocketListener {
            override fun onConnected() {
                LogUtils.e(TAG, "===連接成功====")
                val messageEvent = MessageEvent()
                messageEvent.message = "socket連接成功"
                FloatWindowManager.log("socket連接成功")
                CoroutineScope(Dispatchers.Main).launch{
                    FlowBus.with<MessageEvent>("onConnected").post(this,messageEvent)
                }
            }
            override fun onConnectFailed(throwable: Throwable) {
                LogUtils.e(TAG, "===連接失敗====")
                val messageEvent = MessageEvent()
                messageEvent.message = "socket連接失敗:$currentWebSocketUrl"
                FloatWindowManager.log("socket連接失敗")
            }
            override fun onDisconnect() {
                LogUtils.e(TAG, "===斷開連接====")
                val messageEvent = MessageEvent()
                messageEvent.message = "socket斷開連接"
                FloatWindowManager.log("socket斷開連接")
            }
            override fun onSendDataError(errorResponse: ErrorResponse) {
                LogUtils.e(TAG + "===發(fā)送數(shù)據(jù)失敗====" + errorResponse.description)
                val messageEvent = MessageEvent()
                messageEvent.message = "發(fā)送數(shù)據(jù)失敗--->" + errorResponse.description
                FloatWindowManager.log("發(fā)送數(shù)據(jù)失敗")
            }
            override fun <T> onMessage(msg: String, t: T) {
                LogUtils.e(TAG,"===接收到消息 String===$msg")
                val messageEvent = MessageEvent()
                messageEvent.message = msg
                FloatWindowManager.log("===接收到消息===$msg")
                taskManager?.onHandleMsg(msg)
            }
            override fun <T> onMessage(bytes: ByteBuffer, t: T) {
                LogUtils.e(TAG, "===接收到消息byteBuffer===="+GsonUtils.toJson(bytes))
                val rBuffer = ByteBuffer.allocate(1024)
                val charset = Charset.forName("UTF-8")
                try {
                    val receiveText =
                        charset.newDecoder().decode(rBuffer.asReadOnlyBuffer()).toString()
                    LogUtils.e(TAG, "===接收到消息byteBuffer====$receiveText")
                    val messageEvent = MessageEvent()
                    messageEvent.message = receiveText
                   // FloatWindowManager.log("===收到消息 byte===$receiveText")
                } catch (e: CharacterCodingException) {
                    throw RuntimeException(e)
                }
            }
            override fun onPing(pingData: Framedata) {
                LogUtils.e(TAG, "===心跳onPing===$pingData")
            }
            override fun onPong(framedata: Framedata) {
                LogUtils.e(TAG, "===心跳onPong===$framedata")
                val messageEvent = MessageEvent()
                messageEvent.message = format.format(Date()) + "  | 心跳onPong->"
                FloatWindowManager.log("===心跳onPong===${format.format(Date())}${"->"}$currentWebSocketUrl")
            }
        })
        mWebSocketManager?.start()
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

5.2接收數(shù)據(jù):

private fun initFlowBus() {
    FlowBus.with<MessageEvent>("onConnected").register(this@MainActivity) {
        LogUtils.d(TAG, "收到消息為:$it")
    }
    FlowBus.with<MessageEvent>("onStartVpn").register(this@MainActivity) {
        LogUtils.d(TAG, "收到vpn消息為:$it")
        CoroutineScope(Dispatchers.Main).launch {
            if (it.message == "start" && it.state && Constants.SWITCH_IP) {
                this@MainActivity.sockUrl = it.sockUrl
                LogUtils.d(TAG, "收到代理地址為:${it.sockUrl}")
                AppUtils.prepareVpn(this@MainActivity,it.sockUrl)
               // prepareVpn()
            }
        }
    }
    FlowBus.with<MessageEvent>("onStopVpn").register(this@MainActivity) {
        LogUtils.d(TAG, "收到vpn消息為:$it")
        if (it.message == "stop" && !it.state) {
            AppUtils.stopVpn(this@MainActivity)
        }
    }
}

6.實現(xiàn)的效果如下:

7.項目demo源碼如下:

https://gitee.com/jackning_admin/flowbus-demo

到此這篇關(guān)于Android使用Flow封裝一個FlowBus工具類的文章就介紹到這了,更多相關(guān)Android FlowBus工具類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 獲取Activity棧,判斷當前Activity位置的方法

    獲取Activity棧,判斷當前Activity位置的方法

    下面小編就為大家分享一篇獲取Activity棧,判斷當前Activity位置的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • 如何利用matrix實現(xiàn)圖片倒影效果

    如何利用matrix實現(xiàn)圖片倒影效果

    利用matrix可以實現(xiàn)各種圖片的特效,比如圖片的旋轉(zhuǎn)、縮放、移動,甚至是圖片倒影效果,這篇文章為大家介紹了matrix實現(xiàn)圖片倒影的代碼,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Android開發(fā)中MJRefresh自定義刷新動畫效果

    Android開發(fā)中MJRefresh自定義刷新動畫效果

    本文給大家介紹了MJRefresh自定義刷新動畫效果,包括常見用法等相關(guān)知識,非常不錯,具有參考借鑒價值,感興趣的朋友一起看看吧
    2016-11-11
  • Android啟動頁面定時跳轉(zhuǎn)的三種方法

    Android啟動頁面定時跳轉(zhuǎn)的三種方法

    這篇文章主要介紹了Android啟動頁面定時跳轉(zhuǎn)的三種方法,實現(xiàn)打開一個Android手機APP的歡迎界面后跳轉(zhuǎn)到指定界面的效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Android實現(xiàn)高德地圖首頁效果(上)

    Android實現(xiàn)高德地圖首頁效果(上)

    這篇文章主要為大家詳細介紹了基于Android實現(xiàn)高德地圖首頁效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-08-08
  • HandlerThread的使用場景和用法詳解

    HandlerThread的使用場景和用法詳解

    這篇文章主要介紹了HandlerThread的使用場景和用法詳解,HandlerThread是Android中的一個線程類,它是Thread的子類,并且內(nèi)部封裝了Looper和Handler,提供了更方便的消息處理和線程操作,需要的朋友可以參考下
    2023-07-07
  • Android實現(xiàn)掃描和生成二維碼

    Android實現(xiàn)掃描和生成二維碼

    這篇文章主要為大家詳細介紹了Android實現(xiàn)掃描和生成二維碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Android5.0以上實現(xiàn)全透明的狀態(tài)欄方法(仿網(wǎng)易云界面)

    Android5.0以上實現(xiàn)全透明的狀態(tài)欄方法(仿網(wǎng)易云界面)

    下面小編就為大家分享一篇Android5.0以上實現(xiàn)全透明的狀態(tài)欄方法(仿網(wǎng)易云界面),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Android ViewPager實現(xiàn)圖片輪播效果

    Android ViewPager實現(xiàn)圖片輪播效果

    這篇文章主要為大家詳細介紹了Android ViewPager實現(xiàn)圖片輪播效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Android開發(fā)Jetpack組件ViewModel與LiveData使用講解

    Android開發(fā)Jetpack組件ViewModel與LiveData使用講解

    Jetpack是一個由多個技術(shù)庫組成的套件,可幫助開發(fā)者遵循最佳做法,減少樣板代碼并編寫可在各種Android版本和設(shè)備中一致運行的代碼,讓開發(fā)者精力集中編寫重要的代碼
    2022-09-09

最新評論