【问题标题】:Android: How to implement a "wait for receiving data" in AsyncTaskAndroid:如何在 AsyncTask 中实现“等待接收数据”
【发布时间】:2025-12-26 19:20:07
【问题描述】:

我正在编写一个 Android 应用程序,它将通过 BLE(蓝牙低功耗)向另一台设备发送消息,并且该设备将响应 ACK/NACK 消息。我使用的 BLE 服务将使通信像普通的 UART 通信一样。

我在 AsyncTask 中实现了两个设备之间的通信,因为通信涉及许多发送/接收循环。我可以发送消息和接收消息,问题是我发送消息后,我需要等待至少一段时间(超时)才能收到响应。在这段等待时间内,我需要检查我是否重复收到了有效的响应,超时后我需要停止等待。我知道我们可以让 AsyncTask 休眠,所以休眠时间就是超时。但是,我只能在完整的睡眠时间(例如 3 秒)后才能查看消息,效率不高。

怎么做?

下面是我的异步任务:

public class configTask extends AsyncTask<String, Integer, Integer> {
    @Override
    protected Integer doInBackground(String... message) {

        // Using StringBuilder here just to show the example, 
        // I will add more string here in real situation
        final StringBuilder sb = new StringBuilder(20);
        sb.append("A test message\r");
        sb.trimToSize();
        try {
            byte[] tx_data = String.valueOf(sb).getBytes("UTF-8");

            // This line will send out the packet through a BLE serivce,
            // "mService" is the BLE service that I have initialize in the
            // MainActivity.
            mService.writeRXCharacteristic(tx_data);
        }
        catch (UnsupportedEncodingException e){
            Log.d(TAG, "Encode StringBuilder to byte[] get UnsupportedEncodingException");
        }

        // After sent out the packet, I need to check whether received
        // a valid response here. The receive and parse routine is 
        // implemented in the MainActivity, once the BLE service received a 
        // packet, it will parse it and set a flag to indicate a packet
        // is received.

        // And then other send/receive routines...

        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

    @Override
    protected void onPostExecute(Integer result) {
        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
}

【问题讨论】:

  • 对我来说,AsyncTask 的用法看起来不太好。更像是在它自己的线程上运行的绑定服务。
  • 我是 Android 新手。 BLE 通信作为服务实现。在我的 MainActivity 中,我实现了一个 BroadcastReceiver,它可以获取从 BLE 服务接收到的消息,并在收到消息后对其进行解析。在这种情况下,启动另一个服务会更好吗?

标签: android android-asynctask


【解决方案1】:

以某种方式提出相同的问题Set timeout function with AsyncTask [Android]

您应该在 doInBackground 中实现取消机制并通过超时调用 AsyncTask.cancel() [像那样](https://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable, long))

final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
      @Override
      public void run() {
        AsyncTask.cancel();
      }
    }, 1);

就您而言,您是否考虑过服务?

【讨论】:

  • 但是我不想仅仅实现超时,我需要检查在等待期间是否收到了 BLE 消息。您的代码似乎只是在 1 毫秒后取消 AsyncTask。
  • 我展示了如何实现超时(看门狗),结果应该在doInBackground() 中检查,当你在onPostExecute() 中收到do smth。还是考虑用服务吧。
【解决方案2】:

您可以执行以下操作

numBytes = 0;
for(int i=0; i<300; i++){
    numBytes += mService.read(bytes, .....) //Not sure about signature of your read method so just putting variables generally used.

    //TODO - copy your bytes to main buffer here

    if(numBytes == requiredBytes)
        break
    else
        Thread.Sleep(10);
}

【讨论】: