Android信标库后台服务-视频播放或加载某些API数据时的UI滞后

时间:2019-05-17 14:49:24

标签: android ibeacon altbeacon ibeacon-android android-ibeacon

我正在使用Android Beacon Library开发一个信标应用扫描器(激活蓝牙后在后台)。 问题是,每当我在后台激活扫描仪,并尝试在另一个Activity中使用MediaController播放视频或加载一些API数据时,该视频均无法播放,或者有时播放时滞并且与API加载相同行动。

但是当我禁用扫描仪时,一切正常。

我不知道该库是在另一个线程中还是在阻塞UI的同一线程中运行其服务,所以我想知道如何才能通过多任务解决方案解决此问题。

我用过 huawei HOL-19,API19

这是CustomApplication文件:


import android.R
import android.app.*
import android.content.Context
import android.content.Intent
import android.os.*
import android.util.Log
import com.example.anymarketmobile.views.subactivities.HomeActivity
import org.altbeacon.beacon.*
import org.altbeacon.beacon.powersave.BackgroundPowerSaver
import org.altbeacon.beacon.startup.BootstrapNotifier
import org.altbeacon.beacon.startup.RegionBootstrap

class BackgrounApplicationBeacons : Application(), BeaconConsumer, RangeNotifier {
    //  Init Properties
    lateinit var mBeaconManager: BeaconManager
    var mRegion: Region? = null
    var mMonitor = false
    var mLastDetectedBeacon: Beacon? = null
    val TAG = "==>"

    //  Actions & Callbacks
    override fun onBeaconServiceConnect() {
        mBeaconManager.addRangeNotifier(this)
        try {
            mBeaconManager.startRangingBeaconsInRegion(mRegion!!)
        } catch (e: RemoteException) {
        }
    }

    override fun didRangeBeaconsInRegion(beacons: MutableCollection<Beacon>?, region: Region?) {
        Log.i("==>Beacons:", "${beacons?.size}")
        if (beacons?.size!! > 0) {
            val beacon = beacons.iterator().next()
            if (beacon.id1 != mLastDetectedBeacon?.id1) {
                Log.i("${TAG}beacon detected:", "${beacon.id1} , ${beacon.distance} m")
                mLastDetectedBeacon = beacon
            }
        }
    }

    //  Start monitoring beacons
    fun startMonitoring() {
        mBeaconManager = BeaconManager.getInstanceForApplication(this)
        Log.i("==>", "Application launched:")
        if (mBeaconManager.isMainProcess) {
            mBeaconManager.beaconParsers.clear()
            mBeaconManager.beaconParsers.add(
                BeaconParser().setBeaconLayout(Constants.DEFAULT_BEACONS_LAYOUT)
            )
            mBeaconManager.setEnableScheduledScanJobs(false)
            val backgroundPowerSaver = BackgroundPowerSaver(this)
            mBeaconManager.backgroundBetweenScanPeriod = 0
            mBeaconManager.backgroundScanPeriod = 2100
            mRegion = Region("test", null, null, null)
            // mRegionBootstrap = RegionBootstrap(this, mRegion)
            mMonitor = true
            val builder = notificationBuilder()
            mBeaconManager.enableForegroundServiceScanning(builder.build(), 456)
            Log.i(TAG, "startMonitoring")
            mBeaconManager.applySettings()
            mBeaconManager.bind(this)

        }
    }

    //  Stop monitoring beacons
    fun stopMonitoring() {
        mRegion = null
        mBeaconManager.removeRangeNotifier(this)
        mBeaconManager.unbind(this)
        /*mRegionBootstrap?.disable()
        mRegionBootstrap = null*/
        Log.i(TAG, "stopMonitoring")
        mMonitor = false
        mLastDetectedBeacon = null
    }

    fun isMonitoring() = mMonitor


    //  Forground notification builder
    private fun notificationBuilder(): Notification.Builder {
        val builder = Notification.Builder(this)
        builder.setSmallIcon(R.drawable.ic_search_category_default)
        builder.setContentTitle("Scanning for Beacons")
        val intent = Intent(this, HomeActivity::class.java)
        intent.putExtra(Constants.FOREGROUND_SERVICE_COMMUNICATION_BEACON_SCAN, mMonitor)
        val pendingIntent = PendingIntent.getActivity(
            this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
        )
        builder.setContentIntent(pendingIntent)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                "My Notification Channel ID",
                "My Notification Name", NotificationManager.IMPORTANCE_DEFAULT
            )
            channel.description = "My Notification Channel Description"
            val notificationManager = getSystemService(
                Context.NOTIFICATION_SERVICE
            ) as NotificationManager
            notificationManager.createNotificationChannel(channel)
            builder.setChannelId(channel.id)
        }
        return builder
    }
}

我希望避免任何滞后或缓慢执行。

1 个答案:

答案 0 :(得分:1)

Android蓝牙堆栈的大部分工作都在UI线程上-例如,所有检测回调都在UI线程上进行。 Android信标库会维护自己的后台线程池,一旦从操作系统传入数据包,便会立即将检测处理切换到优先级较低的后台线程。结果,UI线程上的库处理开销很小-仅限于将工作交给每个看到的数据包到不同的线程。

但是,BLE检测处理的操作系统部分是另一回事,其中一些是在UI线程上完成的。如果BLE扫描对UI线程进行大量的Android OS处理,除非同时可见大量BLE设备,否则我会感到惊讶。我尚未在华为HOL-19上进行过专门测试,但已在库存的Android设备(例如Pixel和Nexus设备)上对其进行了测试,并确认在可见到十几个或更少的BLE设备的情况下,UI处理最少。

您可以尝试使用其他设备,查看是否可能是特定于华为HOL-19的问题。