在我的Android应用中,我需要在两个应用之间发送数据。当GameClient初始化后,它将启动三个线程。 第一个将创建一个Socket和ReceivingThread。我需要在一个线程中执行此操作,因为Android不允许我在MainThread上进行网络连接:
new Thread(new Runnable() {
@Override
public void run() {
try {
if (mSocket == null) {
setSocket(new Socket(mAddress, mPort));
Log.d(TAG, "Client-Socket set.");
} else {
Log.d(TAG, "Socket already set. Skip.");
}
mRecCardThread = new ReceivingCardThread();
mRecCardThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
mSendCardThread = new SendingCardThread();
mSendCardThread.start();
此后,我创建了第三个用于发送数据的线程。
当我连接到另一部电话并立即要发送一些数据时,会发生问题。
mConnection.connectToServer(d.getHost(), d.getPort());
mConnection.sendCard(new int[]{0, 0, 0});
我的发送线程试图发送数据,但是通常比setSocket
方法更早被调用。
private synchronized void setSocket(Socket socket) {
Log.d(TAG, "setSocket called");
if (mSocket != null) {
if (mSocket.isConnected()) {
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
mSocket = socket;
if (mClient != null)
mClient.mSendCardThread.notifyAll();
Log.d(TAG, "Notify all, that Socket is set");
}
private class SendingCardThread extends Thread {
BlockingQueue<int[]> mCardQueue = new ArrayBlockingQueue<>(10);
private ObjectOutputStream mOutput;
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
int[] nums = mCardQueue.take();
sendCard(nums);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private synchronized void sendCard(int[] nums) {
try {
if (mOutput == null) {
while (mSocket == null) {
Log.d(TAG, "Waiting for Socket to be set.");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "Not waiting anymore.");
}
mOutput = new ObjectOutputStream(mSocket.getOutputStream());
}
mOutput.writeObject(nums);
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, "Client send:" + Arrays.toString(nums));
}
}
因此,我想让Socket仍为null
时以及创建Socket时唤醒发送线程,以唤醒发送线程以确保Socket开头不为空。 / p>
但这会导致IllegalMonitorStateException
:对象在notifyAll()之前没有被线程锁定。
因此,似乎它尝试进行通知,但发送线程没有等待。但是我不知道如何解决这个问题。我还认为我不理解如何在praxice中使用wait()和notify()。
我希望你们中的一个能帮助我解决这个愚蠢的问题; D