[英]Bluetooth transfer App stops after using InputStream.read() with no error
我正在嘗試使用以下來源制作文件傳輸藍牙應用程序:
http://developer.android.com/guide/topics/connectivity/bluetooth.html
當我嘗試使用InputStream.read()
方法以這種方式獲取InputStream字節時:
public class ConnectedThread extends Thread {
...(some code here)
public void run(){
byte[] buffer = new byte[1024];
int bytes = -1;
//Keep listening to the InputStream while connected
while (true){
try {
bytes = this.mmInStream.read(buffer);
//* this part is not reached
if (bytes==-1){
Log.d("NoData:","-1");
}
}
catch(Exception e){
Log.d("inStream exception:",e.getMessage());
break;
}
}
}
...(some code here)
}
永遠不會到達代碼的下一部分(在這種情況下為"if"
部分),也不會出現Log.D
調試輸出或我放入的其他任何內容。 我剛從LogCat收到此消息:
BluetoothSocket read in: android.net.LocalStocketImpl$SocketInputStream@f7e
b08 len: 1024
要將數據從客戶端傳輸到服務器,我這樣做:
public class MainActivity extends Activity {
...(some code here)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
clientConnect();
//serverConnect();
}
...(some code here)
public void clientConnect(){
Set<BluetoothDevice> devices;
devices = bConfig.getPairedDevices();
if (devices == null){
return;
}
if (devices.size() > 0) {
BluetoothDevice device = devices.iterator().next();
ConnectThread connectTransmit = new ConnectThread(device,bConfig.getBluetoothAdapter(),BluetoothConfig.mUUID);
connectTransmit.start();
Toast.makeText(this, "connected", Toast.LENGTH_SHORT).show();
socket = connectTransmit.mmSocket;
ConnectedThread connectedThread = new ConnectedThread(socket);
//write file bytes to the connected thread, so the thread can receive its own input written bytes later
File file_to_transfer = new File(Environment.getExternalStorageDirectory() + "/txtTransfer.txt");
//get bytes from our File
int size = (int) file_to_transfer.length();
byte[] bytes = new byte[size];
try {
//14b are read succesfully, the whole text file
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file_to_transfer));
buf.read(bytes,0,bytes.length);
buf.close();
}catch (FileNotFoundException e){
Log.d("FileNotFoundException:",e.getMessage());
}catch (IOException e){
Log.d("IOException:",e.getMessage());
}
//send the data to the server
connectedThread.start();
connectedThread.write(bytes);
//connectedThread.cancel();
}
}
...(some code here)
}
AcceptThread
(實現的服務器部分)工作,因為當我運行客戶端部分連接然后傳輸數據時,在設備中進行調試時,服務器部分上的LogCat激活並到達線程的run方法,我調用ConnectedThread
實現,但之后“顯然”讀取字節但它在LogCat上卡住而沒有錯誤。
請讓我知道如何完成讀取字節以移動到流程的下一部分。
謝謝
您被阻止等待更多輸入。
在流結束測試之后,標記為... (some code here)
的部分... (some code here)
應該在讀取循環內 。 注意如果read()
返回-1並不表示“沒有數據”,則表示流結束,您應該關閉套接字並中斷讀取循環。 否則,您應該繼續處理您剛讀過的數據。 目前你只是讀取並忽略所有輸入,直到流結束,這是沒有意義的。 充其量只能處理最后一個部分緩沖區,你不知道它有多長。
在您的客戶端代碼中,您應該讓connectedThread對象保持活動一段時間。 可能是一旦if子句關閉並且它超出了范圍(不太確定GC和所有事情發生了什么),寫入就不會發生並且您的連接沒有關閉但也沒有使用。
在寫入之后在connectedThread內的mmOutStream上調用flush()也可能有所幫助。
就像@EJP建議的那樣,你應該把一些東西放在你的閱讀循環中。
編輯:為了調試你可以添加this.wait(1000);
在您寫入客戶端代碼后立即。
在我看來你應該在閱讀之前驗證某些東西是否在緩沖區中。 從流中讀取是阻止操作,因此應用程序將掛起,直到出現某些數據。 如何在不讀取的情況下檢查InputStream是否為空?
嘗試將run方法更改為:
public void run(){
byte[] buffer = new byte[1024];
int bytesRead = 0;
final int shortSleepTime = 1000;
final int longSleepTime = 5000;
int emptyReadCounter = 0;
int sleepCounter = 0;
int currentSleepTime = shortSleepTime;
//Keep listening to the InputStream while connected
while (bytesRead >= 0){
try {
// if available() returns 0, there is nothing to read yet
if (this.mmInStream.available() != 0){
bytesRead = this.mmInStream.read(buffer);
// Check if we need to reset the sleep counters
if (emptyReadCounter != 0){
emptyReadCounter = 0;
sleepCounter = 0;
currentSleepTime = shortSleepTime;
// We can also do anything else dependent on just waking up
// from a sleep cycle in this block
}
// Do something with my now full buffer
// Remember not to process more than
// 'bytesRead' bytes from my buffer because the
// rest could be filled with crap left over from
// the last iteration
} else {
// Three consecutive empty reads means sleep
if (emptyReadCounter++ >= 3){
if (currentSleepTime != longSleepTime && sleepCounter++ >= 3){
currentSleepTime = longSleepTime;
}
Thread.sleep(currentSleepTime);
}
}
}
catch(Exception e){
Log.d("inStream exception:",e.getMessage());
break;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.