处理程序和多个活动

时间:2013-06-13 08:19:32

标签: android multithreading handler android-bluetooth

好的,我是android的新手,我正在尝试创建一个通过蓝牙与arduino接口的应用程序。我已经看过示例BluetoothChat并看到它如何使用Handler在“服务”,由它产生的线程和MainActivity之间进行通信。 我的问题是我有多个Activity需要使用蓝牙服务。 对于每个Activity,我都有一个像这样的Handler:

        mHandler = new Handler(){
        @Override
        public void handleMessage(Message message) {
            switch (message.what){
           case BtService.CHANGE_STATE:
               if (message.arg1 == BtService.STATE_CONNECTING){
                   Intent i = new Intent (MainActivity.this,ConnectedActivity.class);
                   startActivity(i);

               }
               break;
           }
        }

    };

在服务构造函数中我得到了这个:

    private BtService(){
    btm = BluetoothAdapter.getDefaultAdapter();
    mHandler= new Handler(Looper.getMainLooper());
}

当我需要发送消息时,我这样做:

    private synchronized void setState(int state){
    mHandler.obtainMessage(CHANGE_STATE, state, -1).sendToTarget();
    mState = state;
}

但是各种其他处理程序都没有收到消息。 在here中声明“特定线程的所有Handler对象都接收相同的消息。”所以我无法理解这个问题。 每次启动一个活动时,是否需要将Handler在该Activity中声明的服务传递给它以使其接收消息?这似乎有效,但对我来说似乎不是一个好习惯。

2 个答案:

答案 0 :(得分:5)

如果你想在所有应用程序中发送消息,你应该使用BroadcastReceiver,我知道这是你的最佳方式。

 Intent intent = new Intent(ApplicationConstants.MY_MESSAGE);
 LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

在任何活动中接收消息(您可以在多个活动中使用此消息)

   BroadcastReceiver connectionUpdates = new BroadcastReceiver() {

        @Override
        public void onReceive(Context arg0, Intent intent) {

                     ...//TODO here
        }
    };
    LocalBroadcastManager.getInstance(this).registerReceiver(
            connectionUpdates ,
            new IntentFilter(ApplicationConstants.MY_MESSAGE));

希望这是有帮助的

干杯,

答案 1 :(得分:0)

您可以扩展Application层并使用它来维护线程以检索和管理通过蓝牙连接收集的数据,而不是让每个活动通过蓝牙连接。然后,只需在每个活动中使用一个处理程序,以便根据需要刷新在Application层中收集的数据。

我唯一使用btAdapter和socket的Activity是第一个真正需要蓝牙信息的活动(在菜单和bt配置活动之后)。

在我的第一个活动onRusume()看起来像这样,注释解释..:

@Override
public void onResume() {
super.onResume();

Log.d(TAG, "...onResume - try connect...");

// Set up a pointer to the remote node using it's address.
BluetoothDevice device = btAdapter.getRemoteDevice(address);

// Two things are needed to make a connection:
//   A MAC address, which we got above.
//   A Service ID or UUID.  In this case we are using the
//     UUID for SPP.
try {
  btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
  errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}

// Discovery is resource intensive.  Make sure it isn't going on
// when you attempt to connect and pass your message.
btAdapter.cancelDiscovery();

// Establish the connection.  This will block until it connects.
Log.d(TAG, "...Connecting...");
try {
  btSocket.connect();
  Log.d(TAG, "....Connection ok...");
} catch (IOException e) {
  try {
    btSocket.close();
  } catch (IOException e2) {
    errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
  }
}

// Create a data stream so we can talk to server.
Log.d(TAG, "...Create Socket...");

/**
 * **Here I am kicking off the thread in the application that retrieves all data
 * needed by all my activities.  Then it stores the information in its member
 * variables.  Each activity then refreshes as often as needed, gets the data from
 * the application layer it needs and does some logic on it.**
 */
if(mConnectedThread == null) {
    mConnectedThread = app.new ConnectedThread(btSocket);
    mConnectedThread.start();
}

// This kicks off the handler for this activity that refreshes the activity every
// xxxx ms  and checks the data retrieved from bt in the application layer.
startUpdatingTicketView();
}

这几乎是我如何让它为我工作的核心。

只是另外一个注意事项......我也尝试过在后台服务中管理的bt通信,并且无法使其正常运行。我完全忘记了我遇到的问题是什么,并且很可能使用服务也可以,但我最终没有走这条路。

祝你好运。