You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android如何在Fragment间传递BluetoothController并维持蓝牙连接

Android蓝牙Fragment切换时连接断开的解决方案

问题背景

开发基于蓝牙传输的Android项目,包含MainFragment和VillasFragment。需求是在两个Fragment间共享BluetoothController实例,实现VillasFragment通过该控制器发送数据,但切换Fragment时蓝牙连接会断开,重复初始化逻辑无法解决问题。

核心原因

两个Fragment各自创建独立的BluetoothController实例:

  • 切换Fragment时,原MainFragment的控制器实例随Fragment销毁被回收,导致连接断开
  • VillasFragment重新初始化控制器并调用connect,相当于重建连接,可能出现连接失败或短暂断开

解决方案:将BluetoothController托管给Activity

把控制器的生命周期与宿主Activity绑定,确保Fragment切换时实例保持存活,两个Fragment共享同一个实例。

1. 在宿主Activity中初始化控制器

class MainActivity : AppCompatActivity() {
    lateinit var bluetoothController: BluetoothController
    lateinit var btAdapter: BluetoothAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initBtAdapter()
        val pref = getSharedPreferences(BluetoothConstants.PREFERENCES, MODE_PRIVATE)
        val mac = pref.getString(BluetoothConstants.MAC, "")
        bluetoothController = BluetoothController(btAdapter)
    }

    private fun initBtAdapter() {
        val bManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        btAdapter = bManager.adapter
    }

    // 提供给Fragment获取控制器的方法
    fun getBluetoothController(): BluetoothController = bluetoothController
}

2. 修改MainFragment使用Activity的控制器

移除Fragment内部的控制器初始化,改为从Activity获取:

class MainFragment : Fragment(), BluetoothController.Listener{
    private lateinit var binding: FragmentMainBinding
    private lateinit var bluetoothController: BluetoothController

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 从Activity获取共享控制器
        bluetoothController = (activity as MainActivity).getBluetoothController()
        bluetoothController.setListener(this)

        binding.bConnect.setOnClickListener {
            val pref = activity?.getSharedPreferences(BluetoothConstants.PREFERENCES, Context.MODE_PRIVATE)
            val mac = pref?.getString(BluetoothConstants.MAC, "")
            bluetoothController.connect(mac ?: "", this)
        }

        // 其余UI交互逻辑保持不变
    }

    override fun onDestroyView() {
        super.onDestroyView()
        // 清空监听避免内存泄漏
        bluetoothController.setListener(null)
    }

    // 其余方法保持不变
}

3. 修改VillasFragment共享控制器

同样从Activity获取已存在的控制器,无需重新初始化和连接:

class VillasFragment : Fragment(), BluetoothController.Listener{
    private lateinit var binding: FragmentVillasBinding
    private lateinit var bluetoothController: BluetoothController

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 获取Activity中已初始化的控制器
        bluetoothController = (activity as MainActivity).getBluetoothController()
        bluetoothController.setListener(this)

        // 直接使用控制器发送数据,无需调用connect
        binding.TVillas.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                val vt = progress
                binding.Ttext.text = "Тормоз: $vt"
                bluetoothController.sendMessage("vt=${vt};")
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {}
            override fun onStopTrackingTouch(seekBar: SeekBar?) {}
        })

        // 其余UI交互逻辑保持不变
    }

    override fun onDestroyView() {
        super.onDestroyView()
        bluetoothController.setListener(null)
    }

    // 其余方法保持不变
}

4. 补充BluetoothController的监听切换方法

如果原BluetoothController没有提供切换监听的方法,需要添加:

class BluetoothController(...) {
    private var listener: Listener? = null

    // 添加此方法
    fun setListener(newListener: Listener?) {
        this.listener = newListener
    }

    // 其余原有逻辑保持不变
}

关键注意点

  • 禁止在VillasFragment中调用connect方法,否则会打断现有连接
  • 切换Fragment时通过setListener更新监听者,确保回调能正确分发到当前显示的Fragment
  • 可选:在Fragment销毁时清空监听,避免潜在内存泄漏

内容的提问来源于stack exchange,提问作者Dunkeltod 13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 03:25:54