IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android系统开启蓝牙源码分析(下) -> 正文阅读

[移动开发]Android系统开启蓝牙源码分析(下)

上篇博客我总结了Android打开蓝牙分为4个阶段,第一阶段就是打开蓝牙的方法从APP调到systemServer再到Bluetooth协议栈,最后走到了hardware蓝牙硬件设备。如下图绿色虚线的流程:
在这里插入图片描述

经过了硬件的一些列操作,正真打开了蓝牙设备,下面继续分析。
第二阶段:(对应图中蓝色虚线流程)
在蓝牙打开成功之后,JNI层会通过JniCallbacks的stateChangeCallback方法把消息回调给AdapterService处理,AdapterService则继续把消息给到状态机处理:

void stateChangeCallback(int status) {
        if (status == AbstractionLayer.BT_STATE_OFF) {
            debugLog("stateChangeCallback: disableNative() completed");
            mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
        } else if (status == AbstractionLayer.BT_STATE_ON) {
            mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED);
        } else {
            Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback");
        }
    }

此时的AdapterState处于TurningBleOnState状态,TurningBleOnState在接收到BLE_STARTED消息后,迁入到BleOnState状态:

 private class TurningBleOnState extends BaseAdapterState {
		.......
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case BLE_STARTED:
                    transitionTo(mBleOnState);
                    break;
               ........
    }

每一个状态的迁移,都会触发AdapterService的updateAdapterState,这个方法内部会把状态改变回调给远程的监听者:

void updateAdapterState(int prevState, int newState) {
        mAdapterProperties.setState(newState);
        if (mCallbacks != null) {
            int n = mCallbacks.beginBroadcast();
            debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState(
                    newState) + " to " + n + " receivers.");
            for (int i = 0; i < n; i++) {
                try {
                    mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState);  //远程回调
                } catch (RemoteException e) {
                    debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");
                }
            }
            mCallbacks.finishBroadcast();
        }

这里会远程回调到BluetoothManagerService里面的监听接口,经过handler消息处理机制会调用到bluetoothStateChangeHandler方法:

private void bluetoothStateChangeHandler(int prevState, int newState) {
	
	if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
			.......
			continueFromBleOnState();
	}

}
/**
     * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
     */
    private void continueFromBleOnState() {
 			..........          
            if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
                // This triggers transition to STATE_ON
                mBluetooth.onLeServiceUp();
                persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
            }
      
    }

在这里,正常情况下都会走到mBluetooth.onLeServiceUp()这个方法,至此,第二阶段的流程已经走完。接下来就是进入第三阶段,让Bluetooth继续去完成BLE打开之后的后续的流程。

第三阶段:(对应图中紫色虚线流程)
Bluetooth协议栈的AdapterService在接收到onLeServiceUp的调用之后,会给AdapterState状态机发一条AdapterState.USER_TURN_ON的消息,于是这次操作又交到了AdapterState状态机去处理了。其实我们可以看到,状态机对于整个蓝牙状态的管理是非常重要,同时也让逻辑更加清晰。

void onLeServiceUp() {
        mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
    }

此时状态机处于BleOnState状态,在接收到USER_TURN_ON后,把状态迁入TurningOnState状态:

 private class BleOnState extends BaseAdapterState {

        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case USER_TURN_ON:
                    transitionTo(mTurningOnState);
                    break;

TurningOnState在进入的时候,会去调用AdapterService的startProfileServices方法,从名字就可以看出它是去开启各个ProfileService:

private class TurningOnState extends BaseAdapterState {

        @Override
        int getStateValue() {
            return BluetoothAdapter.STATE_TURNING_ON;
        }

        @Override
        public void enter() {
            super.enter();
            sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
            mAdapterService.startProfileServices();
        }

那具体是哪些Profile呢,我们可以了解一下:

private static final ProfileConfig[] PROFILE_SERVICES_AND_FLAGS = {
            new ProfileConfig(HeadsetService.class, R.bool.profile_supported_hs_hfp,
                    (1 << BluetoothProfile.HEADSET)),
            new ProfileConfig(A2dpService.class, R.bool.profile_supported_a2dp,
                    (1 << BluetoothProfile.A2DP)),
            new ProfileConfig(A2dpSinkService.class, R.bool.profile_supported_a2dp_sink,
                    (1 << BluetoothProfile.A2DP_SINK)),
            new ProfileConfig(HidHostService.class, R.bool.profile_supported_hid_host,
                    (1 << BluetoothProfile.HID_HOST)),
            new ProfileConfig(PanService.class, R.bool.profile_supported_pan,
                    (1 << BluetoothProfile.PAN)),
            new ProfileConfig(GattService.class, R.bool.profile_supported_gatt,
                    (1 << BluetoothProfile.GATT)),
            new ProfileConfig(BluetoothMapService.class, R.bool.profile_supported_map,
                    (1 << BluetoothProfile.MAP)),
            new ProfileConfig(HeadsetClientService.class, R.bool.profile_supported_hfpclient,
                    (1 << BluetoothProfile.HEADSET_CLIENT)),
            new ProfileConfig(AvrcpTargetService.class, R.bool.profile_supported_avrcp_target,
                    (1 << BluetoothProfile.AVRCP)),
            new ProfileConfig(AvrcpControllerService.class,
                    R.bool.profile_supported_avrcp_controller,
                    (1 << BluetoothProfile.AVRCP_CONTROLLER)),
            new ProfileConfig(SapService.class, R.bool.profile_supported_sap,
                    (1 << BluetoothProfile.SAP)),
            new ProfileConfig(PbapClientService.class, R.bool.profile_supported_pbapclient,
                    (1 << BluetoothProfile.PBAP_CLIENT)),
            new ProfileConfig(MapClientService.class, R.bool.profile_supported_mapmce,
                    (1 << BluetoothProfile.MAP_CLIENT)),
            new ProfileConfig(HidDeviceService.class, R.bool.profile_supported_hid_device,
                    (1 << BluetoothProfile.HID_DEVICE)),
            new ProfileConfig(BluetoothOppService.class, R.bool.profile_supported_opp,
                    (1 << BluetoothProfile.OPP)),
            new ProfileConfig(BluetoothPbapService.class, R.bool.profile_supported_pbap,
                    (1 << BluetoothProfile.PBAP)),
            new ProfileConfig(HearingAidService.class,
                    com.android.internal.R.bool.config_hearing_aid_profile_supported,
                    (1 << BluetoothProfile.HEARING_AID))
    };

协议还真是不少啊!每一个服务启动后,都会通知到AdapterService,当所有的协议服务都启动完毕之后,也就意味着蓝牙真正的打开了。
第四阶段:(对应图中橙色虚线流程)
在所有ProfileService都启动完毕之后,AdapterService会判断到此条件,然后会给AdapterState状态机发送AdapterState.BREDR_STARTED,然后迁移到OnState状态:

 private void processProfileServiceStateChanged(ProfileService profile, int state) {
            switch (state) {
                case BluetoothAdapter.STATE_ON:
                		........
                    if (GattService.class.getSimpleName().equals(profile.getName())) {
                        enableNative();
                    } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
                            && mRegisteredProfiles.size() == mRunningProfiles.size()) {  //所有ProfileService都启动完毕
                       .......
                        mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
                    }
                    break;
private class TurningOnState extends BaseAdapterState {
		..........
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case BREDR_STARTED:
                    transitionTo(mOnState);
                    break;

前面已经说了,每次状态的迁移都会通过远程回调接口通知监听者,迁入到OnState也一样。BluetoothManagerService在收到STATE_ON的消息后,在经过Handler消息机制处理后,会走到如下的分支:

else if (newState == BluetoothAdapter.STATE_ON) {
            boolean isUp = (newState == BluetoothAdapter.STATE_ON);
            sendBluetoothStateCallback(isUp);
            sendBleStateChanged(prevState, newState);

显然,这里就是把蓝牙打开的状态通过远程回调接口,以及广播两种方式通知给上层应用。至此,从应用调用打开蓝牙的方法,到收到蓝牙打开的广播,整个蓝牙打开的流程就已经分析完毕!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 11:48:06  更:2021-07-25 11:50:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年3日历 -2024/3/29 21:40:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码