1

我有一部使用 AOA 与 Linux 机器通信的安卓手机。Linux 机器设置为启动连接,然后等待传入数据并将其原样回显给手机。这适用于来自电话的小数据包(小于 1024 字节)。但是,如果我正好发送 1024 个字节,它似乎可以从 Android 端工作,但计算机永远不会看到数据包,只是后面的任何更小的数据包。如果手机尝试发送大于 1024 的数据包,计算机会收到这些数据包,但安卓手机将无法再接收来自计算机的任何数据包。进一步混淆了这个问题,这在过去确实有效,但回滚到手机上传输/接收代码的早期版本似乎没有任何效果。计算机上的代码没有更改。

android 应用程序在启动时检查 USB 附件,如果找到,它会启动侦听器和发送者线程。发送者线程在阻塞队列上等待传出数据包,并在收到它们后立即发送它们。侦听器线程不断尝试从输入流中读取,这会阻塞直到数据可用。这是我用于设置和运行线程的代码:

private boolean openUSB(){
    mUSBManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    mAccessory = mUSBManager.getAccessoryList();
    if (mAccessory != null && mAccessory.length > 0) {
        mParcelFileDescriptor = mUSBManager.openAccessory(mAccessory[0]);
        mFileDescriptor = mParcelFileDescriptor.getFileDescriptor();

        mListener = new Thread() {
            public void run() {
                listenerThread();
            }

        };
        mListener.start();

        mSender = new Thread() {
            public void run() {
                senderThread();
            }

        };
        mSender.start();
        displayText("Connected to USB accessory");

        return true;
    } else {
        displayText("No USB accessory detected"); 
        return false;
    }
}

private void listenerThread(){

    byte packet[] = new byte[SDR_PREFIX_SIZE+SDR_HEADER_SIZE+SDR_MAX_PAYLOAD+SDR_CRC_SIZE];
    FileInputStream input = new FileInputStream(mFileDescriptor);
    try {
        ByteArrayOutputStream incoming = new ByteArrayOutputStream();
        displayText("Listener Started");
        while ( mFileDescriptor != null && input != null ) {
            int read = input.read(packet,0,packet.length);

            /* data in packet gets processed */
        }
    } catch ( Exception e) {
        displayText("Listener Exception - "+e.getMessage(),true);
    }
    displayText("Listener Exited");
}

private void senderThread(){

    displayText("sender started");
    FileOutputStream output=new FileOutputStream(mFileDescriptor);

    try {
        byte data[] = mTransmitQueue.take();
        while (data != null) {
            displayText("Sending packet " + packet + ", "+data.length + " bytes");
            output.write(data);

            data = mTransmitQueue.take();
        }

    } catch ( Exception e) {
        displayText("Sender Exception - "+e.getMessage(),true);
    }
}

过去,我在让监听器和发送器工作时遇到问题,直到我发现一些用于创建文件流的中间对象正在被垃圾收集,但仍然需要。我现在将所有这些中间对象存储到成员变量(mUSBManager、mAccessory、mParcelFileDescriptor、mFileDescriptor)中,以赋予它们持久性。我怀疑这个问题是类似的,但我一直无法取得任何进展。我一直在努力解决这个问题,但没有任何成功,我真的希望其他人能对造成这种情况的原因有所了解。

4

1 回答 1

0

我找到了一种解决方法,扩展用于接收数据的缓冲区似乎可以解决问题,即使现有缓冲区足够大以容纳所有数据包。将缓冲区从 1524 增加到 2524 解决了未接收到传入数据包的问题。这是一个笨拙的解决方案,但它有效。

于 2015-12-28T16:54:49.953 回答