我一直在开发Android应用程序,需要开发如下功能:首先,我需要绑定到已启动的服务,然后在该服务中的对象上调用方法并等待结果。
有问题的对象称为NetworkConnection,它实现了客户端-服务器套接字连接功能。 NetworkConnection有一个mClient对象,该对象已经在运行两个线程-SendingThread和ReceivingThread。我想要做的是让服务请求NetworkConnection.mClient将字符串发送到服务器以获取TXT文件,然后让ReceivingThread接收答复并将其返回给我的原始类,然后让我的原始类继续使用给定的文件。没有该文件,该课程将无法正常工作。
现在,我意识到这不是一个好习惯,向其他线程询问一些内容并等待UI线程上的结果,但是,由于我的设备将通过本地WiFi网络进行通信,因此我不必为此担心太多,因为这很可能会导致应用程序延迟2-3秒,这不是问题。
ConfigurationActivity(调用字符串的类)。
//wait for result!
String configFileString = mBoundService.getFile(R.string.configFileName);
//how do I even tell activity to wait right now?
NetworkService(一项在主要活动中启动的服务,用于保持客户端和服务器之间的活动连接-绑定在某些活动中,这些活动需要服务器提供的东西)。
private NetworkConnection mNetworkConnection;
//cut out useless code
public String getFile(String name){
mNetworkConnection.getFile(name);
}
NetworkConnection(包含客户端和服务器对象的类-客户端在一台设备上初始化,服务器在另一台设备上初始化)
private Client mClient;
public String getFile(String name){
mClient.sendMessage(name);
//what now? Where do I get my string from?
}
// client class
private class Client {
private InetAddress mAddress;
private int PORT;
private final String CLIENT_TAG = "NetworkActivity";
private Thread mSendThread;
private Thread mRecThread;
private Socket mSocket;
public Client(InetAddress address, int port) {
Log.d(CLIENT_TAG, "Creating Client");
this.mAddress = address;
this.PORT = port;
mSendThread = new Thread(new SendingThread());
mSendThread.start();
}
private synchronized void setSocket(Socket socket) {
Log.d(TAG, "setSocket being called.");
if (socket == null) {
Log.d(TAG, "Setting a null socket.");
}
if (mSocket != null) {
if (mSocket.isConnected()) {
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
mSocket = socket;
}
private Socket getSocket() {
return mSocket;
}
public void tearDown() {
try {
getSocket().close();
} catch (IOException ioe) {
Log.e(CLIENT_TAG, "Error when closing server socket.");
}
}
public void sendMessage(String msg) {
try {
Socket socket = getSocket();
if (socket == null) {
Log.d(CLIENT_TAG, "Socket is null, wtf?");
} else if (socket.getOutputStream() == null) {
Log.d(CLIENT_TAG, "Socket output stream is null, wtf?");
}
PrintWriter out = new PrintWriter(
new BufferedWriter(new OutputStreamWriter(getSocket().getOutputStream())), true);
out.println(msg);
out.flush();
} catch (UnknownHostException e) {
Log.d(CLIENT_TAG, "Unknown Host", e);
} catch (IOException e) {
Log.d(CLIENT_TAG, "I/O Exception", e);
} catch (Exception e) {
Log.d(CLIENT_TAG, "Error3", e);
}
Log.d(CLIENT_TAG, "Client sent message: " + msg);
}
class SendingThread implements Runnable {
BlockingQueue<String> mMessageQueue;
private int QUEUE_CAPACITY = 10;
public SendingThread() {
mMessageQueue = new ArrayBlockingQueue<String>(QUEUE_CAPACITY);
}
@Override
public void run() {
try {
if (getSocket() == null) {
setSocket(new Socket(mAddress, PORT));
Log.d(CLIENT_TAG, "Client-side socket initialized.");
} else {
Log.d(CLIENT_TAG, "Socket already initialized. skipping!");
}
mRecThread = new Thread(new ReceivingThread());
mRecThread.start();
} catch (UnknownHostException e) {
Log.d(CLIENT_TAG, "Initializing socket failed, UHE", e);
} catch (IOException e) {
Log.d(CLIENT_TAG, "Initializing socket failed, IOE.", e);
}
while (true) {
try {
String msg = mMessageQueue.take();
sendMessage(msg);
} catch (InterruptedException ie) {
Log.d(CLIENT_TAG, "Message sending loop interrupted, exiting");
}
}
}
}
class ReceivingThread implements Runnable {
@Override
public void run() {
BufferedReader input;
try {
input = new BufferedReader(new InputStreamReader(
mSocket.getInputStream()));
while (!Thread.currentThread().isInterrupted()) {
String messageStr = null;
messageStr = input.readLine();
if (messageStr != null) {
// what do I do with received string now? How do I pass it all the way back?
} else {
break;
}
}
input.close();
} catch (IOException e) {
}
}
}
}