Socket thread blocks main thread when receiving - java

I am using a socket thread.
It takes about 5 to 10 seconds to receive a message after sending a request message.
during that time I want my main thread to show "Please wait" popup.
The process flow of the program looks something like this.
show Popup
create socket thread.
-> this will connect to server
send request message to server
receive message.
My problem is that the show popup does not show up,
until after the socket thread receives its message.
Can anybody tell me a workaround to this problem?
public class LoginActivity extends Activity {
.... <some coded>
public void onClickLogin(View view) {
Log.d(this.toString(), "onClickLogin");
showLoginLoadingPopup();
String login_id = ((EditText)findViewById(R.id.login_id)).getText().toString();
String login_pwd = ((EditText)findViewById(R.id.login_pwd)).getText().toString();
conn = new Connection(handler, 1, null);
conn.start();
conn.sendData(Connection.SSPH_USERCERT, new String[] {login_id, login_pwd});
}
}
public class Connection extends Thread implements ConnectionConstant {
private InetAddress serverAddr;
private int serverPort;
private Socket socket;
PrintWriter out;
BufferedReader in;
private Handler handler;
public Connection(Handler h, int type, ServerClass server) {
Log.d(this.toString(), "Conncetion");
setServerInfo(type, server);
handler = h;
try {
connect();
} catch (Exception e) {
Log.e(this.toString(), "Error", e);
}
}
public void run() {
Log.d(this.toString(), "run");
try {
queue();
disconnect();
} catch (Exception e) {
Log.i(this.toString(), "Information", e);
}
}
private void connect() throws Exception {
if (serverAddr != null)
Log.d(this.toString(), "connect " + serverAddr.getHostName() + "("
+ Integer.toString(serverPort) + ")");
else
Log.d(this.toString(), "connect ");
socket = new Socket(serverAddr, serverPort);
socket.setSoLinger(true, 3000);
// UTF-8
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.i(this.toString(), "Socket connected!");
}
private void queue() throws Exception {
Log.d(this.toString(), "queue");
while (true) {
String sRcv = null;
sRcv = receive();
if (sRcv.length() > 0)
parseData(sRcv);
Thread.sleep(500);
Thread.yield();
}
}
private void send(String str) throws IOException {
Log.d(this.toString(), "send");
if (!socket.isConnected())
return;
Log.i(this.toString(), "Send : " + str);
out.println(str);
}
private String receive() throws Exception {
Log.d(this.toString(), "receive");
if (!socket.isConnected())
return null;
StringBuilder sb = new StringBuilder();
String str = "";
while ((str = in.readLine()) != null) {
Log.i(this.toString(), "Receive : " + str);
sb.append(str + "\n");
}
return sb.toString();
}
}

Use AsyncTask:
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
// show dialog
}
#Override
protected Void doInBackground(Void... params) {
// connect to the server
}
#Override
protected void onPostExecute(Void result) {
// close dialog
}
};
task.execute();
onPreExecute(), onPostExecute() and onProgressUpdate() are invoked on UI thread.
doInBackground() is invoked on background thread.
More about AsyncTask: http://developer.android.com/reference/android/os/AsyncTask.html

dialog = ProgressDialog.show(this, "", "Loading",true);
Runnable myRun = new Runnable(){
public void run(){
//DO ALL NETWORKING
//FINALLY DO THIS
runOnUiThread(new Runnable() {
public void run() {
}
});
};
Thread T = new Thread(myRun);
T.start();

Related

Why is my port source changing with every UDP message I send?

I'm tracking the UDP messages I'm sending from my android phone on Wireshark, but the source port number changes every time I send a message.
So I have two questions:
Is this bad if I want to receive messages back? Or would it be find, just each received message comes through a different port?
If the answer to 1) is yes it is bad, then what should I do to change that?
Here's my code:
edit: Full code
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static final int SERVERPORT = 1111;
public static final String SERVER_IP = "255.255.255.255";
private LinearLayout msgList;
private EditText edMessage;
private int clientTextColor;
private ClientThread clientThread;
private Thread thread;
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msgList = findViewById(R.id.msgList);
edMessage = findViewById(R.id.edMessage);
clientTextColor = ContextCompat.getColor(this, R.color.colorAccent);
handler = new Handler();
}
// Just for displaying messages on device
public TextView textView(String message, int color) {...}
public void showMessage(final String message, final int color) {
handler.post(new Runnable() {
#Override
public void run() {
msgList.addView(textView(message, color));
}
});
}
// Implementation
#Override
public void onClick(View view) {
if(view.getId() == R.id.clear) {
msgList.removeAllViews();
}
if (view.getId() == R.id.send_data) {
// Starting thread
clientThread = new ClientThread();
thread = new Thread(clientThread);
thread.start();
String clientMessage = edMessage.getText().toString().trim(); // Client's Message
showMessage(clientMessage, Color.BLUE); // Just display
if (null != clientThread) {
clientThread.sendMessage(clientMessage + "\r\n");
}
}
}
class ClientThread implements Runnable {
byte[] buffer = new byte[1024];
#Override
public void run() {
try {
while (true) {
DatagramSocket ds = new DatagramSocket(SERVERPORT);
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
ds.receive(dp);
String serverMsg = new String(dp.getData(), 0, dp.getLength());
showMessage("Server: " + serverMsg, clientTextColor);
ds.close();
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
}
void sendMessage(final String message) { // Called by "Send Data" button
new Thread(new Runnable() {
#Override
public void run() {
try {
byte[] msg = message.getBytes();
InetAddress ip = InetAddress.getByName(SERVER_IP);
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(msg, msg.length, ip, SERVERPORT);
socket.setBroadcast(true);
socket.send(packet);
} catch(Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
String getTime() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
return sdf.format(new Date());
}
#Override
protected void onDestroy() {
super.onDestroy();
if (null != clientThread) {
clientThread.sendMessage("Disconnect");
clientThread = null;
}
}
}

How to make socket connection on Android

I'm trying to make a simple app that sends a message taken from an EditText,
using the Java Socket class. I'm trying with AsyncTask, but it works only once and I can't return the socket for reuse in another instance of the class.
Can you give me an example of a background service that opens a communication with a server and returns the Socket?
EDIT:
As required by nandsito; I intend to open a connection using a Button, so this button calls a beckground process that creates the connection with the server, finally returns the Socket. When I press another Button I want to start another task that reuses sockets, write data (for example Sring) receive a response from the server and updates the UI.
It looks simple but I think you have an interesting and challenging problem. If you want to keep the socket open after sending messages through it, you'll need to maintain one or more threads to use that socket because, you know, Android doesn't allow networking on main thread.
Multithread programming is seldom simple and often there is more than one way to do it. E.g. in Android you can use Handlers with Loopers from HandlerThreads, or the classic Java Thread. And also AsyncTask, but I think it doesn't fit this case.
How do you intend to manage the socket lifecycle (i.e. when is it opened or closed), and in which moments is data read/written from/into the socket? Please explain better the matter so I can suggest an implementation.
EDIT
Here's an example Activity with two buttons. One button runs an AsyncTask that creates a socket and its streams, and the other button runs another AsyncTask that writes data into the socket. It's an oversimplified solution, but it should work. Note that the code needs synchronization, for different threads access the socket.
public class MainActivity extends Activity {
private SocketContainer mSocketContainer;
private final Object mSocketContainerLock = new Object();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// onClick attribute of one button.
public void onClickPushMe(View view) {
String serverAddress;
int serverPort;
new CreateSocketAsyncTask(serverAddress, serverPort).execute();
}
// onClick attribute of other button.
public void onClickPushMeToo(View view) {
String text;
new WriteSocketAsyncTask(text).execute();
}
// Class that contains the socket and its streams,
// so they can be passed from one thread to another.
private class SocketContainer {
private Socket mSocket;
private InputStream mSocketInputStream;
private OutputStream mSocketOutputStream;
private SocketContainer(Socket socket, InputStream socketInputStream, OutputStream socketOutputStream) {
mSocket = socket;
mSocketInputStream = socketInputStream;
mSocketOutputStream = socketOutputStream;
}
private Socket getSocket() {
return mSocket;
}
private InputStream getSocketInputStream() {
return mSocketInputStream;
}
private OutputStream getSocketOutputStream() {
return mSocketOutputStream;
}
}
// AsyncTask that creates a SocketContainer and sets in into MainActivity.
private class CreateSocketAsyncTask extends AsyncTask<Void, Void, SocketContainer> {
private final String mServerAddress;
private final int mServerPort;
private CreateSocketAsyncTask(String serverAddress, int serverPort) {
mServerAddress = serverAddress;
mServerPort = serverPort;
}
protected SocketContainer doInBackground(Void... params) {
try {
Socket socket = new Socket(mServerAddress, mServerPort);
return new SocketContainer(socket, socket.getInputStream(), socket.getOutputStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
#Override
protected void onPostExecute(SocketContainer socketContainer) {
super.onPostExecute(socketContainer);
synchronized (mSocketContainerLock) {
mSocketContainer = socketContainer;
}
}
}
private class WriteSocketAsyncTask extends AsyncTask<Void, Void, Void> {
private final String mText;
private WriteSocketAsyncTask(String text) {
mText = text;
}
#Override
protected Void doInBackground(Void... params) {
synchronized (mSocketContainerLock) {
try {
mSocketContainer.getSocketOutputStream().write(mText.getBytes(Charset.forName("UTF-8")));
mSocketContainer.getSocketOutputStream().flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return null;
}
}
}
With this code i connect to a chat, so you can use it similliary to connect with what you want
public class SocialConnectionManager extends AsyncTask<Void, Void, Void> {
public static final int SQL_STEP_LOGIN = 0;
public static final int SQL_STEP_LOGOUT = 1;
public static final int SQL_STEP_SEND = 2;
public static final int SQL_STEP_UPDATE = 3;
final int serverPort = 8080;
private String message, channel, userName, serverIp;
private int step;
private long uniqueId;
private Activity activity;
public SocialConnectionManager(String serverIp, long uniqueId, int step, String userName,
String channel, String message, Activity activity) {
this.message = message;
this.step = step;
this.uniqueId = uniqueId;
this.channel = channel;
this.userName = userName;
this.serverIp = serverIp;
this.activity = activity;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(serverIp, serverPort);
DataOutputStream dataOut = new DataOutputStream(socket.getOutputStream());
switch (step) {
case SQL_STEP_LOGIN:
dataOut.writeInt(step);
dataOut.writeLong(uniqueId);
dataOut.writeUTF(channel);
dataOut.writeUTF(userName);
break;
case SQL_STEP_LOGOUT:
dataOut.writeInt(step);
dataOut.writeLong(uniqueId);
dataOut.writeUTF(channel);
dataOut.writeUTF(userName);
break;
case SQL_STEP_SEND:
long messageId = createRandomId();
messageIds.add(messageId);
dataOut.writeInt(step);
dataOut.writeLong(uniqueId);
dataOut.writeUTF(channel);
dataOut.writeUTF(userName);
dataOut.writeUTF(message);
dataOut.writeLong(messageId);
break;
case SQL_STEP_UPDATE:
dataOut.writeInt(step);
dataOut.writeUTF(message);
break;
}
dataOut.flush();
} catch (UnknownHostException e) {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
((MainActivity) activity).showNetworkAlertDialog(context.getString
(R.string.social_chat_connection_failed));
}
});
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}
private class ReceiveTask extends AsyncTask {
final int clientPort = 5050;
#Override
protected Object doInBackground(Object[] params) {
try {
serverSocket = new ServerSocket(clientPort);
while (true) {
final Socket socket = serverSocket.accept();
DataInputStream dataIn = new DataInputStream(socket.getInputStream());
final int step = dataIn.readInt();
final int userCount = dataIn.readInt();
final String message = dataIn.readUTF();
final String userName = dataIn.readUTF();
switch (step) {
case SocialConnectionManager.SQL_STEP_LOGIN:
if (isLogging) {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
showProgress(false);
}
});
isLogging = false;
isLoggedIn = true;
}
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
userCountView.setText(Integer.toString(userCount));
addMessage(message, userName, step);
}
});
break;
case SocialConnectionManager.SQL_STEP_LOGOUT:
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
addMessage(message, userName, step);
}
});
break;
case SocialConnectionManager.SQL_STEP_SEND:
messageId = dataIn.readLong();
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
addMessage(message, userName, step);
}
});
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String ip = getIpAddress();
if (ip.equals("")) {
((MainActivity) activity).showNetworkAlertDialog(context.getString
(R.string.social_chat_connection_lost));
} else if (!deviceIp.equals(ip)) {
SocialConnectionManager socialConnectionManager =
new SocialConnectionManager(serverIp, 0,
SocialConnectionManager.SQL_STEP_UPDATE, null, null, deviceIp,
activity);
socialConnectionManager.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
};
}
Async task is not worthy for the real time chat.
Get into firebase to use the things easy.
This might help you-
https://www.firebase.com/docs/android/examples.html

Outputting Every Other Time

I have made an application that opens up a socket via a thread and updates based on what is typed. Here is the code:
Server.java:
public class Server {
public static void main(String[] args) throws IOException {
int portNumber = 2392;
boolean listening = true;
System.out.println("Server: Running...");
try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
System.out.println("Server: Connected to Client!");
while (listening) {
new ServerThread(serverSocket.accept()).start();
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection( '" + e.getMessage() + "' );");
} finally {
System.out.println("Server: Disconnecting...");
}
}
}
Server Thread.java:
public class ServerThread extends Thread {
private Socket socket = null;
Scanner reader = new Scanner(System.in);
public ServerThread(Socket socket) {
super("ServerThread");
this.socket = socket;
}
public void run() {
System.out.println("Ruasd");
try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
String outputLine = "";
while (!outputLine.equals("Disconnect")) {
outputLine = reader.nextLine();
out.println(outputLine);
}
socket.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client.java:
public class MainActivity extends Activity {
private Socket socket;
private TextView status;
private BufferedReader in;
private Handler mHandler;
private static final int SERVERPORT = 2392;
private static final String SERVER_IP = "...ip#...";
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_vitals);
status = (TextView) findViewById(R.id.text_status);
new Thread(new CommunicationThread()).start();
}
#Override
protected void onStop() {
super.onStop();
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class CommunicationThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
final String fromServer = in.readLine();
System.out.println("Server: " + fromServer);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// This code will always run on the UI thread, therefore is safe to modify UI elements.
status.setText(fromServer);
}
});
if (fromServer.equals("Disconnect."))
break;
}
} catch (IOException e) {
e.printStackTrace();
}
It works perfectly the first time and outputs to the status TextView correctly. However, when I restart the application, it outputs every other word. For instance, If I type "Hey" "Hi "You" "How", I will see "Hi" and "How" in the TextView the second time I start the application.
What's really odd to me is that when I do System.out.println("Server: " + fromServer) it is outputting all values. Any suggestions are greatly appreciated.
Ok I think I found the problem (got it working for me, that is). In your CommunicationThread, you didn't have a while loop. Also, you need to iterate the server's input until it is null. See below:
class CommunicationThread implements Runnable {
#Override
public void run() {
try {
// keep the connection alive.
while (true) {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String fromServer;
// get server messages until there are none
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// This code will always run on the UI thread, therefore is safe to modify UI elements.
status.setText(fromServer);
}
});
if (fromServer.equals("Disconnect."))
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Please get back to me on how it works out :)

Unable to establish socket connect between two different android devices at different locations with different service providers

I am trying to establish a socket connection between two different devices at different places. I am using Airtel SIM on my android device. I am running following code on the device:
public class MainActivity extends Activity
{
Context context;
TextView info, infoip, msg;
String message = "";
ServerSocket serverSocket;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
Sql s = new Sql(context);
info = (TextView) findViewById(R.id.info);
infoip = (TextView) findViewById(R.id.infoip);
msg = (TextView) findViewById(R.id.msg);
new GetPublicIPTask().execute();
}
private class SocketServerThread extends Thread
{
static final int SocketServerPORT = 8080;
int count = 0;
#Override
public void run()
{
try
{
serverSocket = new ServerSocket(SocketServerPORT);
MainActivity.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
info.setText("Port: " + serverSocket.getLocalPort());
}
});
while (true)
{
Socket socket = null;
try
{
socket = serverSocket.accept();
}
catch (Exception e)
{
e.printStackTrace();
}
count++;
message += "#" + count + " from " + socket.getInetAddress() + ":" + socket.getPort() + "\n";
MainActivity.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
msg.setText(message);
}
});
SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(socket, count);
socketServerReplyThread.run();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
private class SocketServerReplyThread extends Thread
{
private Socket hostThreadSocket;
int cnt;
SocketServerReplyThread(Socket socket, int c)
{
hostThreadSocket = socket;
cnt = c;
}
#Override
public void run()
{
OutputStream outputStream;
String msgReply = "Hello client " + cnt;
try
{
outputStream = hostThreadSocket.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.print(msgReply);
printStream.close();
message += "replied: " + msgReply + "\n";
MainActivity.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
msg.setText(message);
}
});
}
catch (IOException e)
{
e.printStackTrace();
message += "Exception! " + e.toString() + "\n";
}
MainActivity.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
msg.setText(message);
}
});
}
}
public class GetPublicIPTask extends AsyncTask<String, Integer, String>
{
ProgressDialog progressDialog;
String serverResponse = "";
public GetPublicIPTask()
{
progressDialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute()
{
if (!NetWorkInfo.isOnline(context))
{
Toast.makeText(context, "No Internet Connection", Toast.LENGTH_LONG).show();
return;
}
progressDialog.setMessage("Getting IP");
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected String doInBackground(String... sUrl)
{
BufferedReader in = null;
int TIME_OUT = 1000 * 60 * 10;
HttpClient httpclient = new DefaultHttpClient();
HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, TIME_OUT);
HttpConnectionParams.setSoTimeout(params, TIME_OUT);
HttpGet httppost = new HttpGet("http://checkip.dyndns.org");
httppost.setHeader("Content-Type", "application/json");
try
{
HttpResponse response = httpclient.execute(httppost);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuffer sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null)
{
sb.append(line);
}
serverResponse = sb.toString();
return serverResponse;
}
catch (Exception ex)
{
Log.d("Socket Server", "StackTrace : " + ex.getStackTrace().toString());
}
finally
{
try
{
if (in != null)
{
in.close();
}
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
return null;
}
#Override
protected void onPostExecute(String result)
{
if (progressDialog != null && progressDialog.isShowing())
{
progressDialog.dismiss();
}
infoip.setText(serverResponse);
Thread socketServerThread = new Thread(new SocketServerThread());
socketServerThread.start();
super.onPostExecute(result);
}
}
}
And from terminal I am hitting the mobile app:
telnet publicIpAddress 8080
Same process working in local network, but not working in mobile networks.

Android bug in thread

I'm working on an android Quiz app with connection to a server over a socket. On the client side (Android device) I check in a while loop the answers which are given by a server (Java server). The connection and the receiving of the answer all goes good. The problem is that in my class to check for answers there's a bug. To give more information I will include a part of the code here:
public void startClient(){
checkValue = new Thread(new Runnable(){
#Override
public void run() {
try
{
final int PORT = 4444;
final String HOST = "192.168.1.118";
Socket SOCK = new Socket(HOST, PORT);
Log.e("success", "You connected to: " + HOST);
quizClient = new QuizClient(SOCK);
//Send the groupname to the list
PrintWriter OUT = new PrintWriter(SOCK.getOutputStream());
OUT.println(groupName);
OUT.flush();
Thread X = new Thread(quizClient);
X.start();
connected = true;
}
catch(Exception X)
{
Log.e("connection error", "Error: ", X);
}
}
});
checkValue.start();
}
public void testvalue(){
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
while(true){
if(message != null && !message.matches("")){
Thread.sleep(1000);
Log.e("receive", message);
buffer = message;
message = "";
Message msg = new Message();
String textTochange = buffer;
msg.obj = textTochange;
mHandler.sendMessage(msg);
Thread.sleep(3000);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String text = (String)msg.obj;
//call setText here
//String[] myStringArray = new String[];
value.clear();
String[] items = text.split(";");
for (String item : items)
{
value.add(item);
Log.e("message", item);
//System.out.println("item = " + item);
}
if(value.get(0).equals("1")){
questionGroup.setVisibility(View.INVISIBLE);
sendAnswer.setVisibility(View.INVISIBLE);
answer.setVisibility(View.INVISIBLE);
question.setText("");
question.setText(value.get(2));
rad1.setText(value.get(3));
rad2.setText(value.get(4));
rad3.setText(value.get(5));
rad4.setText(value.get(6));
questionGroup.setVisibility(View.VISIBLE);
sendAnswer.setVisibility(View.VISIBLE);
} else if (value.get(0).equals("2")){
questionGroup.setVisibility(View.INVISIBLE);
sendAnswer.setVisibility(View.INVISIBLE);
answer.setVisibility(View.INVISIBLE);
question.setText("");
question.setText(value.get(2));
answer.setVisibility(View.VISIBLE);
sendAnswer.setVisibility(View.VISIBLE);
} else
{
questionGroup.setVisibility(View.INVISIBLE);
sendAnswer.setVisibility(View.INVISIBLE);
answer.setVisibility(View.INVISIBLE);
question.setText(text);
}
}
};
#Override
protected void onStop()
{
if (connected == true){
try {
quizClient.DISCONNECT();
} catch (IOException e) {
e.printStackTrace();
}
}
if(checkValue != null)
{
checkValue.interrupt();
}
super.onStop();
closeApplication();
}
So I make a new instance of this class (where I actually check the incoming stream of data)
public class QuizClient implements Runnable {
//Globals
Socket SOCK;
Scanner INPUT;
Scanner SEND = new Scanner(System.in);
PrintWriter OUT;
public QuizClient(Socket X)
{
this.SOCK = X;
}
public void run()
{
try
{
try
{
INPUT = new Scanner(SOCK.getInputStream());
OUT = new PrintWriter(SOCK.getOutputStream());
OUT.flush();
CheckStream();
}
finally
{
SOCK.close();
}
}
catch(Exception X)
{
Log.e("error", "error: ", X);
}
}
public void DISCONNECT() throws IOException
{
OUT.println("DISCONNECT");
OUT.flush();
SOCK.close();
}
public void CheckStream()
{
while(true)
{
RECEIVE();
}
}
public void RECEIVE()
{
if(INPUT.hasNext())
{
String MESSAGE = INPUT.nextLine();
if(MESSAGE.contains("#?!"))
{
}
else
{
QuizActivity.message = MESSAGE;
Log.e("test", MESSAGE);
}
}
}
public void SEND(String X)
{
OUT.println(X);
OUT.flush();
}
}
So the bug persist I think in the following class:
public void testvalue(){
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
while(true){
if(message != null && !message.matches("")){
Thread.sleep(1000);
Log.e("receive", message);
buffer = message;
message = "";
What I do here is make a thread and check if the "message" is not equals at null. The message come from the other class:
public void RECEIVE()
{
if(INPUT.hasNext())
{
String MESSAGE = INPUT.nextLine();
if(MESSAGE.contains("#?!"))
{
}
else
{
QuizActivity.message = MESSAGE;
Now most of the time this works good but there are 2 problems. When I go out of the page it disconnect from the server (works) I go back on the page and connect again to the server but this time I don't get any values on the screen (receiving is okj but for one of the other reason it does not go good in my handler). Also get an indexoutofboundexception after a time:
question.setText(value.get(2));
A second problem occurs some time while the program runs. There are moments that I also don't get a value on my interface while it correctly receive the input.
So my guess is that my solution of the thread to read in the values is not the best way to handle it. So now I ask to people with more experience what I can do to make this work without major problems? You need to know the connection works and I get the value in my QuizClient class. So the problem need to be in my main class.
My oncreate class:
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
selectgroep = (Spinner) findViewById(R.id.groepen);
questionGroup = (RadioGroup) findViewById(R.id.QuestionGroup);
sendAnswer = (Button) findViewById(R.id.sendAnswer);
rad1 = (RadioButton) findViewById(R.id.radio0);
rad2 = (RadioButton) findViewById(R.id.radio1);
rad3 = (RadioButton) findViewById(R.id.radio2);
rad4 = (RadioButton) findViewById(R.id.radio3);
answer = (EditText) findViewById(R.id.textanswer);
questionGroup.setVisibility(View.INVISIBLE);
sendAnswer.setVisibility(View.INVISIBLE);
answer.setVisibility(View.INVISIBLE);
try {
connect();
} catch (InterruptedException e) {
e.printStackTrace();
}
//Code na het drukken op de knop
startserver = (Button) findViewById(R.id.startserver);
startserver.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startClient();
getID();
testvalue();
}
});
sendAnswer.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Stuur antwoord door en sluit alles af
questionGroup.setVisibility(View.INVISIBLE);
sendAnswer.setVisibility(View.INVISIBLE);
answer.setVisibility(View.INVISIBLE);
answer.setText("");
rad1.setChecked(true);
rad1.setText("");
rad2.setText("");
rad3.setText("");
rad4.setText("");
question.setText("Wachten op server ... ");
}
});
}
Thank you in advance,
Thomas Thooft

Categories