Android 蓝牙4.0 BLE 开发之请求同步实现篇 完全解析

本文详细解析了Android蓝牙4.0 BLE开发中遇到的异步请求导致的兼容性问题,提出通过requestQueue实现请求同步的解决方案。通过使用BleLibrary中的AndroidBle和BleService类,确保蓝牙请求顺序执行并正确处理回调,降低错误率,提高应用的兼容性。
摘要由CSDN通过智能技术生成

开发过Android 蓝牙4.0 BLE的同学都知道,Android的蓝牙开发有非常多的坑,具体坑的集合可见我的前面一篇博客,《Android蓝牙4.0 BLE开发坑总结》,其中不同机型之间的兼容性就是一个很令人头疼的问题,很多问题究其原因是在手机端和智能设备之间发送请求指令和回调时,其方式是异步请求的,即请求完立即结束,等待回调,而回调又在不同的线程中,因此当交互比较频繁并且之间有依赖关系的时候,很容易错误。很多Android手机针对这种情况在底层实现了对蓝牙请求的同步,即有一个requestQueue,使得一个蓝牙请求能够在上一个蓝牙请求的reponse结束之后再发送,保证了顺序执行和正确性。但是有些Android手机没有提供这样的requestQueue,使得错误率大大增加,往往这些问题还不容易发现,从而造成了Android蓝牙开发的兼容性问题。所以,要想做好兼容性,我们必须在app端的应用层就应该提供一套完整的requestQueue请求同步策略。

那么这篇文章,我就给大家介绍一个解决方案,能够使得activity非常轻量级的只管发送蓝牙请求和接受最终数据即可,其他的就交给library来做。具体的全套代码可见:https://github.com/xpg/GizwitsBLE

其中关键的是BleLibrary里的两个类,AndroidBle 和 BleService,其中AndroidBle是UI 和 BleService 之间的桥梁,基本的从发送蓝牙请求到接收蓝牙数据的过程,我们以BluetoothLeGatt Project里的DeviceControlActivity为例:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_connect:
            mBle.requestConnect(mDeviceAddress);
            return true;
        case R.id.menu_disconnect:
            mBle.disconnect(mDeviceAddress);
            onDeviceDisconnected();
            return true;
        case android.R.id.home:
            onBackPressed();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

其中的mBle.requestConnect(mDeviceAddress);就是利用AndroidBle发送了一条蓝牙请求,那么我们看requestConnect做了什么。

@Override
    public boolean requestConnect(String address) {
        BluetoothGatt gatt = mBluetoothGatts.get(address);
        if (gatt != null && gatt.getServices().size() == 0) {
            return false;
        }

        mService.addBleRequest(new BleRequest(RequestType.CONNECT_GATT, address));
        return true;
    }

这里实际上又利用了BleService的强大的requestQueue管理,即mService.addBleRequest(new BleRequest(RequestType.CONNECT_GATT, address));,我们接下来重点看看BleService的requestQueue是如何实现的。

protected void addBleRequest(BleRequest request) {
        synchronized (mRequestQueue) {
            mRequestQueue.add(request);
            processNextRequest();
        }
}

这里很简单,就是把request放入requestQueue中,然后处理Queue中的Request。

/**
     * 1. 处理 mRequestQueue 里的当前请求,同时开启对 当前请求的处理超时 startTimeoutThread
     * 2. 如成功处理完此请求之后,比如 discoverServices,connect,characteristicNotification,readCharacteristic 等,在AndroidBle 里有对应的回调,回调里会调用 bleServiceDiscovered 等
     * 3. bleServiceDiscovered 把内容广播出去
     * 4. 紧接着调用 requestProcessed, 其作用是
     *      a. 取消当前请求的超时处理 clearTimeoutThread
     *      b. 处理下一个请求
     *
     * 综上,RequestQueue, 只有当 1)request处理完时才会执行下一个request 2)ret失败 / request超时时才会执行下一个
     *      否则mCurrentRequest一直指向当前request,
     *      将必须等待回调处理完后,调用 BleService.bleGattXXX --> a) broadcast  b) reqeustProcessed (即这里的1)) --> 下一个request
     */
    private synchronized void processNextRequest() {
        if (mCurrentRequest != null) {
            return;
        }

        if (mRequestQueue.isEmpty()) {
            return;
        }
        mCurrentRequest = mRequestQueue.remove();
        Log.d(TAG, "+processrequest type " + mCurrentRequest.type + " address "
                + mCurrentRequest.address + " remark " + mCurrentRequest.remark);

        startTimeout
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值