Komunikacja między dwoma aplikacjami na Androida
Mam ogromny problem z moją aplikacją na Androida i chciałbym prosić o pomoc.
Obecnie piszę aplikację Android Clietn-Server za pomocą gniazd. Znalazłem wiele korepetycji w Internecie i stworzyłem podstawy do mojego projektu. Jednak wszystkie samouczki dotyczą tylko jednej wiadomości i to wszystko. Muszę wysłać więcej z nich, więc próbowałem go zmodyfikować.
Są to fragmenty kodu odpowiedzialne za serwer i klienta. Reszta nie jest w tej chwili ważna.
Serwer:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
serverStatus = (TextView) findViewById(R.id.server_status);
recivedMsg = (TextView)findViewById(R.id.rec_msg);
SERVERIP = getLocalIpAddress();
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// listen for incoming clients
Socket client = serverSocket.accept();
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Connected." + System.getProperty("line.separator"));
}
});
try {
line = null;
while (connected) {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
if((line = in.readLine())!=null)
{
Log.d("ServerActivity", line);
handler.post(new Runnable() {
@Override
public void run() {
if(recivedMsg.equals("CLOSE"))
{
recivedMsg.append("CLOSE socket");
connected = false;
}
else
{
recivedMsg.append("MSG: " + line + System.getProperty("line.separator"));
}
// do whatever you want to the front end
// this is where you can be creative
}
});
}
else
{
recivedMsg.append("empty" + System.getProperty("line.separator"));
}
}
break;
} catch (Exception e) {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
Klient
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
serverIp = (EditText) findViewById(R.id.server_ip);
connectPhones = (Button) findViewById(R.id.connect_phones);
sendField = (EditText) findViewById(R.id.send_field);
sendMsg = (Button) findViewById(R.id.msg_send);
connectPhones.setOnClickListener(connectListener);
sendMsg.setOnClickListener(sendMessage);
}
@Override
protected void onStop() {
super.onStop();
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "CLOSE";
out.write(outMsg);
out.flush();
// make sure you close the socket upon exiting
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private OnClickListener connectListener = new OnClickListener() {
@Override
public void onClick(View v) {
serverIpAddress = serverIp.getText().toString();
runTcpConnection();
sendMessageToServer("Msg");
}
};
private OnClickListener sendMessage = new OnClickListener() {
@Override
public void onClick(View v) {
sendMessageToServer(sendField.getText().toString());
}
};
private void runTcpConnection() {
try {
s = new Socket(serverIpAddress, SERVERPORT);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "TCP connecting to " + SERVERPORT + System.getProperty("line.separator");
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
SystemClock.sleep(10);
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
};
public void sendMessageToServer(String str) {
try {
s = new Socket(serverIpAddress, SERVERPORT);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = str + System.getProperty("line.separator");
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("", "hello222");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("", "hello4333");
}
}
Na razie urządzenia łączą się poprawnie. Ponadto Wysyłają pierwsze wiadomości połączenia (te wOnClickListener connectListener
).Problem polega na tym, że próbuję wysłać inną wiadomość za pomocąsendMessageToServer
to jest niemożliwe. Wiadomości te są wyświetlane tylko po zniszczeniu aktywności klienta.
Bardzo interesujące jest to bezSystemClock.sleep(10);
słuchaczrunTcpConnection()
zachowuj się dziwnie. Tylko „podłączony”. wyświetla na serwerze.
Czy ktoś może mi powiedzieć, co muszę zrobić, aby móc normalnie wysyłać wiadomości?
EDYTOWAĆ: To są rzeczy, które znalazłem:
Jeśli jestem na połączeniu, wysyłam więcej wiadomości niż wszystkie są puste (null), a po drugim wystąpił błąd połączenia - podłącz ponownie telefonyJeśli jestem na połączeniu, wysyłam więcej wiadomości bez linku s.closesendMessageToServer
przechodzi tylko jedna wiadomość. Po nim nie jest wyświetlany żaden błąd.Formularz wiadomościrunTcpConnection
pokazuje zawsze (z wyjątkiem sytuacji, gdy w tej funkcji nie ma SystemClock.sleep (10))Mam nadzieję, że pomoże to komuś zdiagnozować mój błąd.