使用应用程序上下文将服务绑定到全局可用的Singleton

时间:2019-05-20 13:27:07

标签: android kotlin service singleton

我对iOS / Swift中的Android / Kotlin完全陌生,所以请问这个问题是否太宽泛。

我正在构建一个通过this库与USB设备交互的应用程序。我还向项目添加了this service。该服务负责处理与USB设备的连接。

在“应用程序”中,我将有多个活动,所有活动都通过同一连接进入USB设备。因此,我认为该服务应该绑定到一些全球可用的Singleton。根据“ Bind service from singleton” 它应该是绑定服务的有效方法。

但是我不清楚如何实际制作能够绑定服务的Singleton

当我尝试将Service的绑定从MainActivity(如在库的example code中完成)移动到它自己的Singleton时,方法bindServiceregisterReceiver却没有在Singleton中可用。也许这与上面提到的SO问题提到的“应用程序上下文”有关。

  • 如何制作这样的单身人士?我应该使用object还是class进行定义?
  • bindServiceregisterReceiver的定义在哪里,为什么我无法从Singleton object中使用它们?

这是我对Singleton的尝试。但是似乎我无法从中创建一个Intent,并且上面提到的两个函数都没有定义...

import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import android.content.BroadcastReceiver
import android.content.Context
import android.content.ComponentName
import android.os.IBinder
import android.content.ServiceConnection
import android.os.Handler
import android.os.Message
import java.lang.ref.WeakReference
import android.content.IntentFilter

object BoxManager {

    private var usbService: UsbService? = null
    private var mHandler: BoxManager.MyHandler? = null

    init {
        mHandler = MyHandler(this)

        setFilters()
        startService(UsbService::class.java, usbConnection, null)
    }

    /*
     * Notifications from UsbService will be received here.
     */
    private val mUsbReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                UsbService.ACTION_USB_PERMISSION_GRANTED // USB PERMISSION GRANTED
                -> Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show()
                UsbService.ACTION_USB_PERMISSION_NOT_GRANTED // USB PERMISSION NOT GRANTED
                -> Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show()
                UsbService.ACTION_NO_USB // NO USB CONNECTED
                -> Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show()
                UsbService.ACTION_USB_DISCONNECTED // USB DISCONNECTED
                -> Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show()
                UsbService.ACTION_USB_NOT_SUPPORTED // USB NOT SUPPORTED
                -> Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private val usbConnection = object : ServiceConnection {
        override fun onServiceConnected(arg0: ComponentName, arg1: IBinder) {
            (arg1 as UsbService.UsbBinder).service.let {
                usbService = it
                it.setHandler(mHandler)
            }
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            usbService = null
        }
    }

    private fun startService(service: Class<*>, serviceConnection: ServiceConnection, extras: Bundle?) {
        if (!UsbService.SERVICE_CONNECTED) {

            val startService = Intent(this, service)
            if (extras != null && !extras.isEmpty) {
                val keys = extras.keySet()
                for (key in keys) {
                    val extra = extras.getString(key)
                    startService.putExtra(key, extra)
                }
            }
            startService(startService)
        }
        val bindingIntent = Intent(this, service)
        bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE)
    }

    private fun setFilters() {
        val filter = IntentFilter()
        filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED)
        filter.addAction(UsbService.ACTION_NO_USB)
        filter.addAction(UsbService.ACTION_USB_DISCONNECTED)
        filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED)
        filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED)
        registerReceiver(mUsbReceiver, filter)
    }

    /*
     * This handler will be passed to UsbService. Data received from serial port is displayed through this handler
     */
    private class MyHandler(activity: MainActivity) : Handler() {
        private val mActivity: WeakReference<MainActivity>

        init {
            mActivity = WeakReference(activity)
        }

        override fun handleMessage(msg: Message) {
            when (msg.what) {
                UsbService.MESSAGE_FROM_SERIAL_PORT -> {
                    val data = msg.obj as String
                    Toast.makeText(mActivity.get(), "DATA: ${data}", Toast.LENGTH_LONG).show()
                }
                UsbService.CTS_CHANGE -> Toast.makeText(mActivity.get(), "CTS_CHANGE", Toast.LENGTH_LONG).show()
                UsbService.DSR_CHANGE -> Toast.makeText(mActivity.get(), "DSR_CHANGE", Toast.LENGTH_LONG).show()
            }
        }
    }
}

0 个答案:

没有答案