#java #android
#java #Android
Вопрос:
Я написал серверно-клиентскую систему на Java (клиент работает как на Windows, так и на Android). Все работает нормально, кроме одного: когда я пытаюсь подключить сокет к IP-адресу, на котором не запущен сервер, моя программа выдает ошибку через AlertDialog на Android, а через a System.out.println("ERROR: bla bla bla...");
и все работает нормально. Но есть некоторые IP-адреса, которые замораживают мои устройства. Появляется черный экран, и через 20/30 секунд приложение перестает отвечать.
Вот мой код:
public class Client {
// stuffs
public void connect() {
try {
socketContainer = new CreateSocket(ip, port).execute().get();
if (socketContainer != null) {
connected = true;
}
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
connected = false;
}
}
// Other stuffs
private class SocketContainer {
private Socket socket;
private ObjectOutputStream out;
private ObjectInputStream in;
public SocketContainer(Socket socket, ObjectInputStream in, ObjectOutputStream out) {
this.socket = socket;
this.out = out;
this.in = in;
}
public Socket getSocket() {
return socket;
}
public ObjectOutputStream getOut() {
return out;
}
public ObjectInputStream getIn() {
return in;
}
}
private class CreateSocket extends AsyncTask<Void, Void, SocketContainer> {
private String address;
private int port;
private CreateSocket(String address, int port) {
this.address = address;
this.port = port;
}
@Override
protected SocketContainer doInBackground(Void... voids) {
try {
Socket socket = new Socket(address, port);
socket.connect(new InetSocketAddress(InetAddress.getByName(address), port), 7000);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
return new SocketContainer(socket, in, out);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(SocketContainer sContainer) {
super.onPostExecute(sContainer);
synchronized (lock) {
socketContainer = sContainer;
}
}
}
Комментарии:
1. Что такое createSocket? Асинхронная задача. Не используйте .get() на нем!!!
2. Почему? Объект SocketContainer создается с помощью метода .get() createSocket
3. Нет, он создан с
new
помощью оператора. Избавьтесь от этого .get() .
Ответ №1:
Я сам нашел решение!
Я размещаю решение для тех, у кого такая же проблема:
из developer.android.com:
AsyncTask имеет public final Result get ()
метод и public final Result get (long timeout, TimeUnit unit)
. Я заменил socketContainer = new CreateSocket(ip, port).execute().get();
на socketContainer = new CreateSocket(ip, port).execute().get(5, TimeUnit.SECONDS);
. Таким образом, если клиенту не удастся подключиться к серверу через 5 секунд, будет выдана ошибка (в моем случае AlertDialog).
Комментарии:
1. Всегда приятно найти решение самостоятельно. Но… Очень плохое «решение». Избавьтесь от этого .get() и обработайте результат doInBackground в onPostExecute. Вот как вы должны использовать asynctask. Напишите «обычный» код.