如何closures在Android的屏幕旋转的BluetoothSocket的?

我正在做一个使用蓝牙连接的应用程序。 我在onCreate()调用蓝牙连接并在MainActivity onDestroy()中closures它:

 // Bluetooth private Bluetooth bt; private boolean registered = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt = new Bluetooth(this); bt.enableBluetooth(); bt.setCommunicationCallback(this); bt.connectToName(bt.getBluetoothDevice(this)); IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); registerReceiver(mReceiver, filter); registered = true; } @Override public void onDestroy() { super.onDestroy(); if(registered) { unregisterReceiver(mReceiver); registered=false; } bt.removeCommunicationCallback(); bt.disconnect(); if (handler != null && runnable != null) { handler.removeCallbacks(runnable); } } 

该应用程序还支持LANDSCAPE和PORTRAIT模式(使用两种不同的布局)。 当旋转屏幕时,由于布局不同, MainActivity调用onCreate()onDestroy函数。 出于这个原因,我得到了以下错误:

 @@@ ABORTING: INVALID HEAP ADDRESS IN dlfree addr=0x5a71aa38 A/libc: Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 1051 (le.bluetoothled) 

正如我在无效堆地址和致命信号11中发现的 ,它来自BluetoothSocket的close()方法。 首先,我认为我们在旋转屏幕的时候不需要closures蓝牙,所以我试图用这种方法来检测手机的旋转事件 ,而在旋转发生时忽略closures,但是它不起作用。 因此,我认为我们可能需要在屏幕旋转时closures蓝牙,但是我得到了上述错误。 我不知道如何解决这个问题,你能帮我解决这个问题吗? 我正在使用这个蓝牙lib与disconnect()如下:

 public void disconnect() { try { socket.close(); } catch (IOException e) { if(communicationCallback!=null) communicationCallback.onError(e.getMessage()); } } 

正如我目前的解决scheme是使用睡眠。 我在closures套接字之前添加了Thread.sleep (1000) 。 这是工作。 但我认为这不是一个很好的解决scheme。

Solutions Collecting From Web of "如何closures在Android的屏幕旋转的BluetoothSocket的?"

你不能在Activity(参见SOLID)原理中使用蓝牙相关的东西。 活动只是一个用户界面。 您应该创build单独的服务,这将独立于后台的用户界面运行,并pipe理所有蓝牙相关的操作。 从你的Activity绑定到onResume()方法中的服务,并在onPause()方法中解除绑定。 您可以从ServiceConnection获取bt-控制接口,在绑定期间通过服务传递。 有一个很棒的蓝牙例子 – https://github.com/googlesamples/android-BluetoothChat 。 唯一的缺点 – 它使用Handler传递消息。 我已经修改了它 – 现在有另一个线程,接收所有的状态消息和调用callback。 随意使用这个代码: https : //github.com/AlexShutov/LEDLights

你可以在你的activity中添加Fragment并调用setRetainInstnce这个片段来处理方向的变化。 用蓝牙将你的逻辑移入Fragment 。 看看如何在这里和这里实现这个。

试试这个代码

 @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); //disconnect your bluetooth } 

在清单文件中将这个标签添加到尊重的活动标签中。 将此标记添加到相关活动中的清单后,Activity可以保留其状态,并且在定向更改期间,不调用onDestroy(),并且不closures蓝牙套接字。

机器人:configChanges = “keyboardHidden |方向|屏幕尺寸”