2012-10-31 121 views
10

所以我實現了Android USB附件API,這樣我可以在我的手機插上我的筆記本電腦運行Linux和它把手機插入USB附件模式。然後,我可以訪問附件,打開它,然後開始閱讀它。我的代碼看起來幾乎與the documentation中的示例相同。主要區別在於我使用單獨的讀取和寫入方法,並通過本機代碼中的JNI訪問它們。從Android的USB配件中讀取拋出IOException異常ENODEV

這裏是它變得有趣的地方。在成功讀/寫一兩秒鐘後,筆記本電腦的批量傳輸寫入開始發出超時錯誤,然後在Android中對USB附件的讀取調用拋出帶ENODEV錯誤代碼的IOException。這是電纜仍然連接,UsbManager仍列出列表中的附件,我仍然有權限。

爲了增加它的奇怪,我發現,如果我把一個100毫秒睡在讀取循環,這個問題基本消失(雖然它仍然偶爾會發生)。在那裏睡覺不僅僅是一個可怕的混亂,但它會在我的應用程序中引入無法容忍的延遲。睡眠時間越短,黑客的效率越低,在睡眠時間爲10毫秒時效率越低。

我發送周圍使用批量傳送(但不那麼實時該批量傳輸是不夠的)實時數據的20-30kbps,和傳輸大小爲50〜800字節的範圍在約20 -30Hz。它可能是USB的限制嗎?我沒有很多的經驗,所以我基本上把它當作網絡套接字來對待。我應該排隊較小的消息,並將它們一起發送,但頻率較低但傳輸量較大?小型,高頻率的批量傳輸是否存在問題?我會研究這一點,但我基本上在這裏抓秸稈。

硬件:

  • 筆記本電腦是運行Ubuntu 10.04和使用的libusb 1.0.0。
  • 手機是Galaxy Nexus S運行的Android 4.1.2版本。

回答

6

因此,雖然我仍然不明白正在發生的一切,但實施雙緩衝方案解決了我的問題。

我發現,全速一個Java Android應用程序讀取曾與ENODEV問題沒有任何問題,這導致我的結論是,Java本地接口是我的問題的根源。

以前,我是從UsbAccessory直接從輪詢方式從JNI調用的方法閱讀。關於從本地代碼到Java,然後從Java到本機Android內核的過渡顯然使所有的事情都變得粗暴。

我的修復是讀/寫的UsbAccessory從Java的只有線程(沒有JNI調用),然後緩衝該數據由JNI調用的方法讀/寫。

看起來像一個魅力的工作。在配件方面,我非常一致地發送超時之前,然後最終如上所述在Android端IOExeception,現在我沒有超時,沒有IOExceptions。我仍然有點好奇究竟是什麼導致了這種行爲,但我認爲這需要強大的JNI功夫才能理解。

相關問題