how to update interface to MainActivity from thread activity in different class? - android

now i'm making socket connection to connect multiple client to one server. everything fine, i make thread in different class. But when i will fill textView with string from thread activity, i can't. please help
this MainActivity:
public class MainActivity extends Activity {
private static int port = 6000;
TextView txt;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = (TextView) findViewById(R.id.txtCommand);
txt.setText("Server : ");
ServerSocket server1 = null;
Server gameServer = new Server();
try {
server1 = new ServerSocket(port);
// .. server setting should be done here
} catch (IOException e) {
System.out.println("Could not start server!");
// return ;
}
while (true) {
Socket client = null;
try {
client = server1.accept();
gameServer.handleConnection(client);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Server {
private ExecutorService executor = Executors.newCachedThreadPool();
public void handleConnection(Socket client) throws IOException {
PlayerConnection newPlayer = new PlayerConnection(this, client);
txt.setText(newPlayer.getuname());
this.executor.execute(newPlayer);
}
// add methods to handle requests from PlayerConnection
}
and this thread adctivity :
public class PlayerConnection implements Runnable {
private Server parent;
private Socket socket;
private PrintWriter out;
private BufferedReader in;
String line;
protected PlayerConnection(Server parent, Socket socket) throws IOException {
this.parent = parent;
this.socket = socket;
this.in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
this.out = new PrintWriter(new OutputStreamWriter(
socket.getOutputStream()));
}
public void run() {
while(!this.socket.isClosed()) {
try {
//int nextEvent = this.in.readInt();
line = in.readLine();
System.out.println("Server Receive : "
+ line);
out.println("Server Sent :" +line);
System.out.println("SEND : "
+ line);
out.flush();
if (line == null){
this.socket.isClosed();
break;
}
} catch (IOException e) {}
}

I realized that you have a while loop that never ends in your onCreate method. try to move that loop in to your thread. this loop blocks inputs of your application.
while (true) {
Socket client = null;
try {
client = server1.accept();
gameServer.handleConnection(client);
} catch (IOException e) {
e.printStackTrace();
}

you can use handler or runOnUiThread method.

Related

Android 6.0 cant create socket

I cant create a simple TCP connection to my server.
I created a AsyncTask to send messages, but it didn't work.
I added INTERNET and ACCESS_NETWORK_STATE to the permissions.
I don't know what else to try.
public class ServerCommunicator extends AsyncTask<String,Void,Void>{
public static String SERVER_IP = "192.168.2.148";
public static int SERVER_PORT = 1337;
public static String SERVER_PW = "adsfadsf";
public Context context;
#Override
protected Void doInBackground(String... params) {
//Create Command
CommandFactory cmdFactory = new CommandFactory();
Command cmd = cmdFactory.createCommand();
System.out.println("Cmd created..");
//-----
try {
System.out.println(SERVER_IP);
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
System.out.println("Created serverAddr "+ SERVER_IP);
Socket socket = new Socket(serverAddr,SERVER_PORT);
System.out.println("Socket created..");
//sends the message to the server
PrintWriter mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
String msg2Send = Crypter.Encrypt(cmd.toString(), SERVER_PW);
sendMsgAsByteArr(socket, msg2Send);
Command recCmd = cmdFactory.extractCommandFromStr(receiveMsg(socket));
socket.close();
Toast.makeText(context, recCmd.id, Toast.LENGTH_LONG).show();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static void sendMsgAsByteArr(Socket socket, String msg) {
try {
socket.getOutputStream().write(msg.getBytes());
System.out.println("sent cmd..");
} catch (IOException e) {
e.printStackTrace();
}
}
private static String receiveMsg(Socket socket) {
String msg = "";
int c;
ArrayList<Byte> incoming = new ArrayList<Byte>();
try {
while((c = socket.getInputStream().read())!=-1) {
incoming.add((byte)c);
}
byte[] allBytes = new byte[incoming.size()];
for(int i = 0; i < incoming.size(); i++) {
allBytes[i] = incoming.get(i);
}
msg = new String(allBytes);
} catch (IOException e) {
e.printStackTrace();
}
return msg;
}
}
My program runs till Socket socket = new Socket(serverAddr, SERVER_PORT); then it stops. It doesn't show any stack trace or errors.
Any ideas?
I debugged your code, and while there were multiple issues, none were related to Android 6.
I created a simplified version of your code and got it working.
One issue is that your context reference was null, so I set it in the constructor.
Another issue is that you were trying to show a Toast on a background thread, which won't work.
Another issue was your send and receive methods, they didn't work for me.
Here's the simplified code that I got working with a TCP/IP server, tested on both Android 4.4.4 and Android 6.
You can take this and expand on it as needed:
public class ServerCommunicator extends AsyncTask<String,Void,String> {
public static String SERVER_IP = "11.222.33.444";
public static int SERVER_PORT = 1234;
public Context context;
public ServerCommunicator(Context c) {
this.context = c;
}
#Override
protected String doInBackground(String... params) {
try {
System.out.println(SERVER_IP);
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
System.out.println("Created serverAddr "+ SERVER_IP);
Socket socket = new Socket(serverAddr,SERVER_PORT);
System.out.println("Socket created..");
//sends the message to the server
PrintWriter mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
String msg2Send = "{\"HelloWorld\", \"1234\"}";
mBufferOut.println(msg2Send);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String result = in.readLine();
System.out.println("result: " + result);
socket.close();
return result;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
Toast.makeText(context, result, Toast.LENGTH_LONG).show();
}
}
}

Android client getting all the inputStreamReader at the deco from the server

I'm asking for a little help here..
I made a Android app in order to get messages from a server. The app just have to show the server's messages and nothing else.
the thing is nothing is shown in the UI, all the messages are shown when I disconnect the server.
It's frustrating because the app get the data's, just don't show them before the disconnection of the server.
Here is my code :
public class SlimpleTextClientActivity extends Activity {
private TextView textView;
private Socket client;
private PrintWriter printwriter;
private BufferedReader bufferedReader;
//Following is the IP address of the chat server. You can change this IP address according to your configuration.
// I have localhost IP address for Android emulator.
private String CHAT_SERVER_IP = "192.168.2.2";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_slimple_text_client);
textView = (TextView) findViewById(R.id.textView1);
ChatOperator chatOperator = new ChatOperator();
chatOperator.execute();
}
/**
* This AsyncTask create the connection with the server and initialize the
* chat senders and receivers.
*/
private class ChatOperator extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
try {
client = new Socket(CHAT_SERVER_IP, 6666); // Creating the server socket.
if (client != null) {
printwriter = new PrintWriter(client.getOutputStream(), true);
InputStreamReader inputStreamReader = new InputStreamReader(client.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
} else {
System.out.println("Server has not bean started on port 4444.");
}
} catch (UnknownHostException e) {
System.out.println("Faild to connect server " + CHAT_SERVER_IP);
e.printStackTrace();
} catch (IOException e) {
System.out.println("Faild to connect server " + CHAT_SERVER_IP);
e.printStackTrace();
}
return null;
}
/**
* Following method is executed at the end of doInBackground method.
*/
#Override
protected void onPostExecute(Void result) {
Receiver receiver = new Receiver(); // Initialize chat receiver AsyncTask.
receiver.execute();
}
}
/**
* This AsyncTask continuously reads the input buffer and show the chat
* message if a message is availble.
*/
private class Receiver extends AsyncTask<Void, Void, Void> {
private String message;
#Override
protected Void doInBackground(Void... params) {
while (true) {
try {
if (bufferedReader.ready()) {
message = bufferedReader.readLine();
publishProgress(null);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
#Override
protected void onProgressUpdate(Void... values) {
textView.append( message + "\n");
}
}
}
Hope that someone have an idea because here... I don't x)
Simon !
EDIT :
So... I went to java to test my code (simplification with the System.out.println)
Here is my code :
public class MainClass {
public static void main(String[] args) throws Exception {
final Socket client;
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
try{
client = new Socket("192.168.2.2", 6666);
InputStreamReader inputStreamReader = new InputStreamReader(client.getInputStream());
// create new buffered reader
br = new BufferedReader(inputStreamReader);
int value=0;
String monChar = null;
String maChaine = null;
//System.out.println(maChaine);
// reads to the end of the stream
while((value = br.read()) != -1)
{
// converts int to character
char c = (char) value;
maChaine = maChaine + c;
}
}catch(Exception e){
e.printStackTrace();
}finally{
// releases resources associated with the streams
if(is!=null)
is.close();
if(isr!=null)
isr.close();
if(br!=null)
br.close();
}
}
}
The thing is that I can't reach maChaine.
This does the same thing that before : I only can reach my String when the server is disconected.
If I put a "System.out.println(maChaine);" in my While it will print something at each rows and if I put it after it will only do something if the server is disconected.

ServerSocket.accept() doesn't works in second time

I'm beginer in android and i'm trying develop a connection TCP server.
I have this class:
public class JavaTCPServer {
public static void send(String aMessage) {
final String msg = aMessage;
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Socket socket = null;
try {
ServerSocket serverSocket = GlobalSingleton.getInstance().getServerSocket();
socket = serverSocket.accept();
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println(msg);
printWriter.flush();
printWriter.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
socket = null;
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
});
thread.start();
}
}
private ServerSocket serverSocket; //Created in GlobalSingleton Class...
try {
serverSocket = new ServerSocket(Constantes.TCP_PORT);
} catch (IOException e) {
e.printStackTrace();
}
I can send message normally in the first time, but when i try to send message the second time the software remains in line: socket = serverSocket.accept(); and the message in printWriter.println(msg) is not sent.
Additional Information
When i kill the app in settings and open i can send once.
Any questions don't hesitate ask me.
Thanks for all!
Your code only accepts one connection, processes it, and then exits. It does not behave as you have described.
You need a loop.
You also need to start a separate thread to handle each connection.
And calling a method that accepts connections send() is inside out and back to front.
I solved my own problem.
I wrote my class as the follow bellow code:
public class JavaTCPServer {
private ServerSocket serverSocket;
private String message;
private Handler updateConversationHandler;
private Thread serverThread = null;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public ServerSocket getServerSocket() {
return serverSocket;
}
public void setServerSocket(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
}
public JavaTCPServer() {
setUpdateConversationHandler(new Handler());
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
public Handler getUpdateConversationHandler() {
return updateConversationHandler;
}
public void setUpdateConversationHandler(Handler updateConversationHandler) {
this.updateConversationHandler = updateConversationHandler;
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(Constantes.TCP_PORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(
socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
private String messageSend;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.setInput(new BufferedReader(new InputStreamReader(
this.clientSocket.getInputStream())));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
Central central = GlobalSingleton.getInstance()
.get_current_central();
if (central != null) {
if ((central.getStep() <= central.getObjetivo()) &&
(central.getStep() == 99)){
try {
messageSend = getMessage();
PrintWriter printWriter = new PrintWriter(
clientSocket.getOutputStream(), true);
printWriter.println(messageSend);
printWriter.flush();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
printWriter.println(Constantes.EXIT_CONFIG);
printWriter.flush();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
central.setStep(central.getStep() + 1);
}
}
/*
* try { String read = input.readLine();
* updateConversationHandler.post(new updateUIThread(read)); }
* catch (IOException e) { e.printStackTrace(); }
*/
}
}
public BufferedReader getInput() {
return input;
}
public void setInput(BufferedReader input) {
this.input = input;
}
}
}
With this class you can send and receive tcp messages all the time.
Thanks for all help!
Serversocket.accept() function is for accepting a new client and connecting with the client, for messages you need to use DataInputStream() and DataOutputStream() after connecting with the server. This happens because for the first time server accepts the new client and process further but after this it does not get a new connection and it waits for new connection at serversocket.accept().

Java desktop client does not send message to android emulator

I am developing a client server application. My client is a java application and my server is an android emulator. I want to send message from client to server but no message received on android emulator.
Java Desktop Client Code
Socket s = null;
BufferedReader get = null;
PrintWriter put = null;
try {
s = new Socket("127.0.0.1", 6000);
put = new PrintWriter(s.getOutputStream(), true);
put.println("hi");
}
catch(Exception ex)
{
}
Android Server Code
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
private EditText textbox;
public static final int SERVERPORT = 6000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.text2);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
Relevant quote from the documentation (scroll down to the section for Network Address Space:
Each instance of the emulator runs behind a virtual router/firewall service
that isolates it from your development machine's network interfaces and settings
and from the internet. An emulated device can not see your development machine
or other emulator instances on the network. Instead, it sees only that it is
connected through Ethernet to a router/firewall.
The virtual router for each instance manages the 10.0.2/24 network address
space — all addresses managed by the router are in the form of 10.0.2.<xx>,
where <xx> is a number. Addresses within this space are pre-allocated by the
emulator/router as follows:
And then they proceed to show the pre-allocated addresses in a table.

How to stop Socket to send a lot of useless data when closed?

I use these codes for communicating between devices. If i close or kill the client app, the server app gets thousands of useless data. The textView in the server side is full of this: Client says: null. If i close the client twice, the server stops with StackOverFlowError. How can i make the code to dont send this null values when the app stops? Or can i filter the server side to do nothing when getting this data?
Client:
public class Client extends Activity {
private Socket socket;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.0.2.2";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
Server:
public class Server extends Activity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
public static final int SERVERPORT = 1599;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.text2);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
}
I think you should use a delimiter character, to tell the Server your Client it's about to die. Add that character of code in onPause method of your Android Activity/Fragment.
Then in your Server, just get the String or byte and compare it against your Delimiter String/Character and stop the Server listening for the Connection.
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is here. You aren't checking the result of readLine() for null. If it returns null, the peer has closed the connection and you should do likewise, and exit this loop. You can probably get rid of the isInterrupted() test as well.
Also, if you get any IOException other that a read timeout when reading from a socket, the connection is dead and you must close the socket and exit your loop.

Categories

Resources