I am working with an app which uses two threads in order to read and send data to server. Each thread runs a while loop; a que holds a que of commands which are dequed to send to the server. This way I can line up a large number of commands which are dequed and sent to the server one by one.
The command sender is as such
class writeThread extends AsyncTask<Object, Object, Object>
{
byte[] buffer;
LittleEndianDataOutputStream outputStream;
@Override
protected void onPreExecute()
{
}
@Override
protected Object doInBackground(Object... params)
{
try
{
buffer = new byte[4096];
outputStream = new LittleEndianDataOutputStream(dataHolder.connection.getOutputStream());
try
{
dataHolder.flags latestFlag;
while (true)
{
try
{
latestFlag = dataHolder.sendFlags.remove();
ByteBuffer sendBytes = ByteBuffer.allocate(128);
sendBytes.order(ByteOrder.LITTLE_ENDIAN);
switch (latestFlag)
{
case sendDataRequest:
sendBytes.putInt(20);
outputStream.write(sendBytes.array());
break;
case getSelectedData:
sendBytes.putInt(21);
sendBytes.put(dataHolder.latestSelected.getBytes());
outputStream.write(sendBytes.array());
break;
case disconnect:
sendBytes.putInt(254);
sendBytes.put(dataHolder.latestSelected.getBytes());
outputStream.write(sendBytes.array());
break;
}
}
catch (NoSuchElementException ex){}
}
}
catch (IOException ex) {}
}
catch (Exception ex){};
return null;
}
}
The read loop looks as such
while (inputStream.read() > -1)
As a result, the app ends up taking up 50% of processing power of the phone. Are there any suggestions on how to optimize socket listening and data sending?
Note: Yes I know I am using a try catch for the queue instead of and if statement to check if the queue not empty. I am sure that the error throwing is not helping the optimization but I don’t think it would push the processor to 50%. Let me know if you need anymore info.
The problem with your implementation is that you are basically doing a busy wait – if there is nothing to send, it immediate goes to the exception handler and tries again – thus taking up all the cpu on that core.
What you want instead is a way to wait until an event is available. I suggest that you create a HandlerThread, and use a Handler that is associated with that thread to handle writing to the data stream.
And then you would create messages with the appropriate id and data, and send them to the handler with handler.sendMessage()
Alternately (and perhaps more simply), if you made your dataHolder.sendFlags collection an ArrayBlockingQueue, rather than whatever it is currently (I’m guessing ArrayList or similar?), then, when you go to remove the next element with ArrayBlockingQueue.take(), it will wait until something is available (without performing a busy wait that takes up all the available cpu time)