Java 如何通过配置更改管理Android上的蓝牙连接?
问题:Java 如何通过配置更改管理Android上的蓝牙连接?,java,android,multithreading,sockets,bluetooth,Java,Android,Multithreading,Sockets,Bluetooth,问题: 如何管理(连接、读取、写入、断开)通过配置更改保持的蓝牙连接 首选使用与设备版本2.2“Froyo”兼容的解决方案 问题… 无论是BluetoothDevice还是BluetoothSocket都不能保留在onSaveState中 为了实现这一点,必须在单独的线程上进行12秒的阻塞调用。启动Runnable是执行长任务的推荐方法,但在配置更改后尝试恢复是一场噩梦。官方文件指出了三种不同的解决方案 使用,这是不推荐的(严重?!) 设置android:configChanges=“key
如何管理(连接、读取、写入、断开)通过配置更改保持的蓝牙连接 首选使用与设备版本2.2“Froyo”兼容的解决方案 问题…
- 无论是
还是BluetoothDevice
都不能保留在BluetoothSocket
中onSaveState
- 为了实现这一点,必须在单独的线程上进行12秒的阻塞调用。启动
是执行长任务的推荐方法,但在配置更改后尝试恢复是一场噩梦。官方文件指出了三种不同的解决方案Runnable
- 使用,这是不推荐的(严重?!)
- 设置android:configChanges=“keyboardHidden | orientation”,如下图所示。但是,这并不能解释所有类型的配置更改
- 取消并重新启动任务,如。在这种情况下,这可能会再浪费12秒
- 进一步的研究让我找到了,但这似乎只能在完成时更新UI,而不能提供更新
- BluetoothHDP示例使用服务。服务似乎侧重于进程间的通信,以及在活动生命周期之外保持的需要。我不需要这些功能中的任何一个
,已替换不推荐使用的
getLastNonConfigurationInstance()
。此时,似乎最好的选择是使用setRetainInstance(true)
生成一个持久的非UI片段 我会使用一个服务来解决这个问题,该服务将处理您的蓝牙连接,并使该服务与您的活动进行对话,如中所述
然后,您可以使用ASyncTask简单地显示/隐藏一个对话框,并在轮换时取消/重新启动ASyncTasks,这是由您提到的示例
完成的
服务并不是很可怕,可能是解决您问题的最佳工具。您可以尝试使用它来处理所有问题,并在必要时调用主要活动
所以这是一个静态方法来获取MySingleton对象的实例,每次调用getInstance时都是同一个实例。您可以将所有蓝牙对象“存储”在其中,它不会被破坏,也不会从每个活动中访问
public class MySingleton {
private static MySingleton instance;
public static MySingleton getInstance() {
if (null == instance) {
instance = new MySingleton();
}
return instance;
}
private MySingleton() {
}
}
有很多解决办法。如果不使用片段,则最简单的选项是重写OnRetainonConfiguration实例()。不要介意API已被弃用,这只是因为他们希望您使用片段(公平地说,Fragment.setRetainInstance()使整个问题变得更容易解决)。这个API在很长一段时间内不会有任何进展
我要做的是重写onRetainonConfiguration()以返回“this”,即对死活动实例的引用,然后从onCreate()复制所需的对象引用,即:
或者你也可以使用服务,但我个人不喜欢。毫无疑问,这对跨流程的工作很有用,但除此之外,它们是寻找问题的解决方案
最后,一般来说,您可以将“全局”数据安全地填充到应用程序上下文中。为此,您需要将android.app.Application子类化,并在清单中使用该属性。在这里,在全局静态数据中保留对应用程序对象的引用也是很有用的,这样AsyncTasks和其他无上下文的代码就可以始终访问应用程序上下文,而不必无缘无故地传递上下文参数
class MyApp extends Application {
...
public static MyApp context;
...
@Override
public void onCreate() {
super.onCreate();
context = this;
... set up global data here ...
}
...
}
切勿将应用程序模型(逻辑或数据)放置在可视/UI组件中。正如你所看到的,他们来来去去,改变
存放与UI无关的内容(如数据收集、实时连接、线程等)的位置:
- 应用程序类。涵盖所有其他组件的生命周期。
就像一个全球单身汉。您可以将其用于临时存储
例如:
public class App extends Application {
private static Beer sBeer;
public static void brbHoldMyBeer(Beer b){
sBeer = b;
}
public static Beer imBackWheresMyBeer(){
return sBeer;
}
}
另外,在应用程序类中使用静态线程执行器服务将有助于保留正在运行的任务
- 正在运行的后台服务。活动、片段等可以绑定/解除绑定和发布命令/请求。这是建议在应用程序范围内运行进程和数据的地方
- 带有
setRetainInstance(true)
的非可视片段。这里的非可视意味着它是一个附加到活动的虚拟片段,但不显示任何视图。它只是用作活动的可保留对象持有者。建议将其用于活动范围内的流程和数据
据我所知,android为每个应用程序提供的应用程序类都有自己的生命周期。在极少数情况下,它也可以在不破坏整个应用程序的情况下被销毁。你是说单独的单身班吗?你能提供一个你在这里谈论的代码示例吗?我并没有真正尝试过蓝牙连接,但不应该破坏singleton类。很抱歉设置了格式,我不是一个SO导出程序,但它只是一个普通的单例类,在这个类中,您将拥有与蓝牙连接相关的所有内容公共类Singleton{private static Singleton instance;publicstatic Singleton getInstance(){if(null==instance){instance=new Singleton();}返回实例;}private Singleton(){}}`感谢您的澄清!你能用密码更新你的答案吗。您可以将每行缩进4个空格,使其格式类似于代码。是否值得为此活动创建一个片段,以便我可以使用setRetainInstance
?“保留”碎片是否能够在方向改变时旋转和调整自身大小?还有,教我Appl的一个子类
public class App extends Application {
private static Beer sBeer;
public static void brbHoldMyBeer(Beer b){
sBeer = b;
}
public static Beer imBackWheresMyBeer(){
return sBeer;
}
}