我正在编写一个使用蓝牙连接的应用程序,通过蓝牙从COM端口读取一些数据。我正在使用ViewPager
来显示几个片段,我用它来显示一些数据(每个片段以不同的方式)。该应用程序有2个活动:
MainActivity
- 初始化蓝牙连接并管理提到的片段Activity
用于搜索蓝牙设备当MainActivity
启动时,它会激活蓝牙,以防它关闭并显示第一个片段。我可以通过按操作面板中的按钮来扫描设备。
我的问题很简单 - 我想在初始化MainActivity
之后将一些初始数据(关于连接)推送到片段,并且在建立BT连接之后我想推送一些数据(大约10个读取) / sec)仅限于可见片段。
我尝试在所有片段中使用LocalBroadcastManager来执行此操作,但broadcastReceiver
未提前注册,并且它不会收到所有消息。我试图将注册移到片段类中的onCreate
,但它也没有用。我也试图实现主要活动的回调接口,但我得到了NPE。
除了这个问题,我担心它可能不是更新一个或多个有关更改的片段问题的最佳解决方案。我愿意接受建议。
主要活动类:
@Override
protected void onStart() {
super.onStart();
if (!bluetoothAdapter.isEnabled()) {
Intent enableBluetoothIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetoothIntent, REQUEST_ENABLE_BLUETOOTH);
} else {
if (btService == null) {
btService = new BluetoothConnectionService(this, msgHandler);
}
}
}
private final Handler msgHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Intent intent = new Intent(STATUS_EVENT);
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BluetoothConnectionService.STATE_CONNECTED:
intent.putExtra("status", "Connected");
// tell fragments about the state change
break;
case BluetoothConnectionService.STATE_CONNECTING:
intent.putExtra("status", "Connecting");
// tell fragments about the state change
break;
case BluetoothConnectionService.STATE_NONE:
intent.putExtra("status", "Not connected");
// tell fragments about the state change
break;
default:
intent.putExtra("status","Unknown state");
break;
}
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
}
};
BTService部分:
public void setCurrentConnectionState(int currentConnectionState) {
this.currentConnectionState = currentConnectionState;
msgHandler.obtainMessage(MainActivity.MESSAGE_STATE_CHANGE, currentConnectionState, -1).sendToTarget();
}
public BluetoothConnectionService(Context context, Handler handler){
this.context = context;
this.msgHandler = handler;
setCurrentConnectionState(STATE_NONE);
}
其中一个片段:
public class ConnectionStatusFragment extends Fragment {
TextView connectionStatus;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_connection_info, container, false);
connectionStatus = (TextView) rootView.findViewById(R.id.connectionStatus);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(broadcastReceiver, new IntentFilter(MainActivity.STATUS_EVENT));
return rootView;
}
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
connectionStatus.setText(intent.getStringExtra("status"));
}
};
}
答案 0 :(得分:0)
重新思考你的设计沿着MVC线并将它应用于android到Data-Model,它以MVC方式与Fragments使用的适配器/视图协作。片段内的适配器被连接到源自模型的数据更改事件......
在后台,关闭用户界面并与您的片段正交,建立您的连接并更新您的数据模型。无需将有关BT连接的信息传递给您的片段。为什么违反了关注点?它是你需要了解BT连接的模型,而不是你的VIEW!
用于更新数据模型的所有连接和IO都封装在您的MODEL操作/流程中。除了“数据模型已更改”之外,您的视图不必了解任何其他内容。您的片段必须具有的所有内容是事件(数据已更改),以便它可以为您的适配器触发“已更改” - 然后将负责更新相应片段中的UI。
将它实际应用于android / fragment并猜测一下你的设计,我认为你的片段的contstructors可以利用一个接口,允许你构建View / Fragment,而不管你的实际数据模型的状态如何。在实例化时,片段及其适配器不知道在不同模块中到达BT连接的数据的状态。片段只需要使用一个接口来容纳'model-has-changed'事件。
我认为你可以使用'looper'和围绕事件进行合作的处理程序。这可能意味着Model需要在View / fragment类中引用处理程序对象。该处理程序用于包含模型状态更改的消息。
模块协调步骤:
1.A。在片段中构造处理程序,为looper上的消息创建对接收者对象的引用
2.A。构造模型,包括参考上面的处理程序。
2.b中。在模型中做BT东西和IO。当'模型改变'时,获取其内容表示您的视图需要知道的关于'模型改变'的消息。
2.C。在View层/片段中发送将由处理程序接收的消息(参见1.a.)。
<强>示例:强>
看到答案here的结尾,看看片段/视图如何从looper接收消息,然后调整UI ......