Я работаю над своим Android-приложением, и мне нужно разработать функциональность следующим образом: сначала мне нужно привязаться к запущенному сервису, затем вызвать метод объекта в этом сервисе и дождаться результата.
Рассматриваемый объект называется NetworkConnection, и он реализует функциональность соединения сокета клиент-сервер. NetworkConnection имеет объект mClient, который уже выполняет два потока - SendingThread и ReceivingThread. Я хочу, чтобы служба попросила NetworkConnection.mClient отправить на сервер строку, запрашивающую TXT-файл, затем ReceivingThread получила ответ и вернула его моему исходному классу, затем мой исходный класс продолжил работу с данный файл. Класс не может работать без этого файла.
Теперь я понимаю, что это не очень хорошая практика - просить что-то в другом потоке и ждать результата в потоке пользовательского интерфейса, но, поскольку мои устройства будут взаимодействовать через локальную сеть Wi-Fi, я не слишком беспокоюсь об этом, поскольку, скорее всего, приложение будет работать с задержкой в 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 (класс, который содержит объекты Client и Server - клиент инициализируется на одном устройстве, сервер на другом)
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) {
}
}
}
}