我的应用程序使用蓝牙连接远程控制机器人,但我无法写入(向机器人发送字节),因为我收到了一个非常奇怪的致命错误。
这是我的应用程序类负责蓝牙连接,我需要把它放在那里因为多个活动使用连接(当时只有一个)。代码取自BluetoothChat示例。
public class BluetoothRemoteControlApp extends Application {
// . . .
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
// . . .
public void run() {
try {
// blocking function, error is here
mmSocket.connect();
} catch (IOException e) {
try {
mmSocket.close();
} catch (IOException e2) {
e2.printStackTrace();
}
connectionFailed();
return;
}
synchronized (BluetoothRemoteControlApp.this) {
mConnectThread = null;
}
// start connected thread
connected(mmSocket, mmDevice);
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
// . . .
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
communicationHandler.obtainMessage(BT_WRITE, -1, -1, buffer).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(String data) {
byte[] out = data.getBytes();
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
r = mConnectedThread;
}
// Perform the write unsynchronized
// This is where my app fails (commenting here makes my app run)
r.write(out);
}
// . . .
}
具体来说,我的应用在r.write(out);
功能内的write(String data)
失败了。我从另一个使用手机加速度计的活动中调用它,如下所示:
public class AccelerometerControl extends Activity implements SensorEventListener {
BluetoothRemoteControlApp appState;
// . . .
protected void onCreate(Bundle savedInstanceState) {
// . . .
appState = (BluetoothRemoteControlApp) getApplicationContext();
}
public void onSensorChanged(SensorEvent event) {
// . . .
// send data to robot
appState.write("s,"+wheelLeft+","+wheelRight);
}
}
我得到的错误日志是这样的:
08-16 21:33:39.471: E/AndroidRuntime(13644): FATAL EXCEPTION: main
08-16 21:33:39.471: E/AndroidRuntime(13644): java.lang.NullPointerException
08-16 21:33:39.471: E/AndroidRuntime(13644): at com.bluetooth.BluetoothRemoteControlApp.write(BluetoothRemoteControlApp.java:212)
08-16 21:33:39.471: E/AndroidRuntime(13644): at com.bluetooth.activities.AccelerometerControl.onSensorChanged(AccelerometerControl.java:170)
08-16 21:33:39.471: E/AndroidRuntime(13644): at android.hardware.SensorManager$ListenerDelegate$1.handleMessage(SensorManager.java:580)
08-16 21:33:39.471: E/AndroidRuntime(13644): at android.os.Handler.dispatchMessage(Handler.java:99)
08-16 21:33:39.471: E/AndroidRuntime(13644): at android.os.Looper.loop(Looper.java:137)
08-16 21:33:39.471: E/AndroidRuntime(13644): at android.app.ActivityThread.main(ActivityThread.java:4424)
08-16 21:33:39.471: E/AndroidRuntime(13644): at java.lang.reflect.Method.invokeNative(Native Method)
08-16 21:33:39.471: E/AndroidRuntime(13644): at java.lang.reflect.Method.invoke(Method.java:511)
08-16 21:33:39.471: E/AndroidRuntime(13644): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-16 21:33:39.471: E/AndroidRuntime(13644): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-16 21:33:39.471: E/AndroidRuntime(13644): at dalvik.system.NativeStart.main(Native Method)
我无法理解出了什么问题,NullPointerException很酷,但对我来说并没什么帮助。第212行是r.write(out);
行。
问题在于ConnectThread
mmSocket.connect();
内部没有进一步(这是阻塞功能)。我没有建立连接,但也没有失败,因此mConnectedThread
从未创建过。当尝试写入null
对象时,我得到了NullPointerException。
我能想到这个新问题的唯一解决方案是制作一个超时线程,然后进行某种“握手”,以便我的手机将我的设备识别为合法机器人,以防用户选择错误的设备。 / p>