Wait for input for only X amount of time - android

I am trying to read in data from an input stream, but if the program does not receive data for X amount of time, I would like to terminate the attempt and return a -1. I was previously using Thread.sleep( X ) but then realized that thats a completely incorrect approach. If anyone has any ideas please let me know. Here is my code for reading from the input stream...
try {
// Read from the InputStream
bytes = mmInStream.read(buffer, 0, length);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(MainMenu.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
// Start the service over to restart listening mode
BluetoothService.this.start();
//break;
}

You can use Future to do this.
First, you need a class which will be returned as "future" value:
public class ReadResult {
public final int size;
public final byte[] buffer;
public ReadResult(int size, byte[] buffer) {
this.size = size;
this.buffer = buffer;
}
}
Then you need to use executor service and use get(long timeout, TimeUnit unit) like this:
ExecutorService service = Executors.newSingleThreadExecutor();
Future<ReadResult> future = service.submit(new Callable<ReadResult>() {
#Override
public ReadResult call() throws Exception {
bytes = mInStream.read(buffer, 0, length);
return new ReadResult(bytes, buffer);
}
});
ReadResult result = null;
try {
result = future.get(10, TimeUnit.SECONDS);
} catch (InterruptedException e1) {
// Thread was interrupted
e1.printStackTrace();
} catch (ExecutionException e1) {
// Something bad happened during reading
e1.printStackTrace();
} catch (TimeoutException e1) {
// read timeout
e1.printStackTrace();
}
if (result != null) {
// here you can use it
}
In that way you will be able to achieve your goal. Plz note that its better to subclass Callable class which will accept inputstream as constructor argument then using class variables.

You could start a new Thread and in there wait for x amount of time. Pass a reference to your activity and once the time is over, you can call a method in your activity from the Time Thread.
eg.
Thread time = new Thread() {
Activity foo;
public addActivity(Activity foo) {
this.foo = foo;
}
public void run() {
Thread.sleep(x);
// Once done call method in activity
foo.theTimeHasCome();
}
}.start();
I hope this helps!

Related

What is the behaviour of writing to a closed OutputStream? Why doesn't my thread terminate?

When another thread calls closeConnection(), the thread doesn't reach
Log.d("Subscriber", "Client thread has ended.");
Why is this? What is the blocking behaviour of a stream that has been closed? I thought trying to write or flush to it would generate an IOException, but it seems the code is still blocking somewhere. Where? I can't find info on what happens when you interrupt() on a write, or what happens when writing to a closed outputstream.
public void closeConnection() {
try {
this.interrupt();
autoCloseOutputStream.close();
} catch (IOException e) {
Log.w("Subscriber", "IOException when closing stream. Buffer might not have been flushed to client.");
}
}
#Override
public void run() {
Log.d("Subscriber","Client thread has started.");
ByteBuffer pgnAndDataBytes=null;
while(true) {
try {
pgnAndDataBytes=fmsByteBufferSubscriberQueue.take();
} catch (InterruptedException e) {
break;
}
Log.d("Subscriber","Still running thread");
try {
autoCloseOutputStream.write(pgnAndDataBytes.array());
autoCloseOutputStream.flush();
} catch (IOException e) {
break;
}
}
Log.d("Subscriber", "Client thread has ended.");
}
The output is as follows:
Still running thread
Still running thread
Still running thread
Close called.
And nothing more. Where is it blocking and why?
Have a volatile boolean shouldClose that you set to true on closeConnect(). Incorporate the boolean into the condition check of the while loop.
boolean done = false;
while(!shouldClose && !done) {
try{
autoCloseOutputStream.write(pgnAndDataBytes.getInt());
} catch(BufferUnderflowException bue) {
final ArrayList<Byte> remainder = new ArrayList<Byte>(3);
while(!shouldClose && !done) {
try {
remainder.add(pgnAndDataBytes.get());
} catch(BufferUnderflowException ex) {
autoCloseOutputStream.write(remainder.toArray(new Byte[remainder.size()]);
done = true;
}
}
}
}

My thread doesnt swap quickly enough on Android

So I have 2 threads (among others) on my application, one that modify an object (in the example , setting the position of a rectangle) and call methods so the second thread can send it on network.
First thread:
public void run(){
while(mIsRunning){
Log.i("MovingRectThread", "Run");
mX += 10;
mRect.setPos(mX,mY);
//Send Rect
mInterface.writeData(mRect);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Second thread:
public void run(){
int commandSize=-1;
byte[] bufferR = new byte[ANSWER_SIZE];
int answerResult = 0;
while(mIsRunning){
Log.i("ProcessThreadGraphic", "Run");
switch(mState){
case IDLEREAD:
//****************
try {
commandSize = mmInStream.read(bufferR, 0, ANSWER_SIZE);
}
catch (IOException e) {
connectionLost();
}
// We received something
if(commandSize != -1 && bufferR[0] == 0x02){
answerResult = bufferR[2];
if(answerResult == 0){
//Authorize sending again
mState = IDLEWRITE;
}
}
//*********************
break;
case IDLEWRITE:
//Trying to send something
if(mBuffer != null ){
try {
mmOutStream.write(mBuffer);
mBuffer = null;
mState = IDLEREAD;
Thread.yield();
} catch (IOException e) {
connectionLost();
}
}
//**************
break;
default:
Log.e(TAG, "Error: state unknown");
break;
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
and mInterface.writeData only end to call to:
public void write(byte[]buffer){
mBuffer = buffer;
}
My problem is, the threads are not working well together: one is looping multiple time before the other restart, which doesn't fit my needs as you can probably imagine, I need the first one to modify my object once, then the second thread to send it, and then only modify the object again...
Hope I've been clear enough.

Implement a timeout in BluetoothSocket inputstream.read() in Android

Is it possible to implement a timeout in an inputstream.read() function from a BluetoothSocket in Android?
I've tried using Thread.sleep() but this only pauses my activity.
---Update---
I had an idea, make 2 thread code herereads(t1 & t2) where each thread interrupt other, one of them(t1) do a sleep(5000) then interrupt the other thread(t2), from the other side the other thread(t2) if in read the inputstream detects some character as 0x0D interrupt the other thread(t1), but here is my question, does anybody can help me? because i didn't use interrupt() method of threads, I hope someone can help me, thank you...
---Update---
public void run(){
while(true){
try {
char r;
String respuesta = "";
while (true) {
r = (char) mmInStream.read();
respuesta += r;
if (r == 0x3e) {
break;
}
}
respuesta = respuesta.replaceAll(" ", "");
Log.d("respuesta", respuesta);
rHandler.obtainMessage(MESSAGE_READ, -1, -1, respuesta).sendToTarget();
} catch (IOException readException) {
Log.e("ServicioGeneral", "Error de lectura", readException);
this.interrupt();
connectionLost();
// posibly break();
}
}
}
This is my implementation when something comes in a different Thread, the problem is that the timeout will be reached if i dont get the 0x3e character from de mmInStream.
I supposed that in the second example i must use a notifyAll(), but, when do I have to start the readThread()?
Thank you, #weeman
You could do something like this:
InputStream in = someBluetoothSocket.getInputStream();
int timeout = 0;
int maxTimeout = 8; // leads to a timeout of 2 seconds
int available = 0;
while((available = in.available()) == 0 && timeout < maxTimeout) {
timeout++;
// throws interrupted exception
Thread.sleep(250);
}
byte[] read = new byte[available];
in.read(read);
This way you are able to initially read from a stream with a specific timeout. If u want to implement a timeout at any time of reading you can try something like this:
Thread readThread = new ReadThread(); // being a thread you use to read from an InputStream
try {
synchronized (readThread) {
// edit: start readThread here
readThread.start();
readThread.wait(timeOutInMilliSeconds);
}
catch (InterruptedException e) {}
using this you may need some kind of event handler to notify your application if the thread actually read something from the input stream.
I hope that helps!
----edit:
I implemented an example without using any handlers.
Socket s = new Socket("localhost", 8080);
final InputStream in = s.getInputStream();
Thread readThread = new Thread(new Runnable() {
public void run() {
int read = 0;
try {
while((read = in.read()) >= 0) {
System.out.println(new String(new byte[]{ (byte) read }));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
synchronized (readThread) {
readThread.start();
try {
readThread.wait(2000);
if(readThread.isAlive()) {
// probably really not good practice!
in.close();
System.out.println("Timeout exceeded!");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
A Kotlin extension function for socket read with timeout:
fun InputStream.read(
buffer: ByteArray,
offset: Int,
length: Int,
timeout: Long
): Int = runBlocking {
val readAsync = async {
if (available() > 0) read(buffer, offset, length) else 0
}
var byteCount = 0
var retries = 3
while (byteCount == 0 && retries > 0) {
withTimeout(timeout) {
byteCount = readAsync.await()
}
delay(timeout)
retries--
}
byteCount
}

problem in understanding java sockets

I have an app in java which is playing the rolle of a server .For limiting the number of incoming connections I'm using a ThreadPool server.
But I have a few problems understanding a part of the code:
Here is y code:
protected ExecutorService threadPool =
Executors.newFixedThreadPool(5);
public ThreadPooledServer(BlockingQueue queue,int port) {
this.serverPort = port;
this.queue=queue;
}
while (!isStopped()) {
Socket clientSocket = null;
try {
System.out.println("Serverul asteapta clienti spre conectare la port" +serverPort);
clientSocket = serverSocket.accept();
clientconnection++;
System.out.println("Serverul a acceptat clientul cu numarul:"
+ clientconnection);
} catch (IOException e) {
if (isStopped()) {
System.out.println("Server Stopped.");
return;
}
throw new RuntimeException("Error accepting client connection",
e);
}
WorkerRunnable workerRunnable = new WorkerRunnable(queue,clientSocket);
this.threadPool.execute(workerRunnable);
}
this.threadPool.shutdown();
System.out.println("Server Stopped.");
}
private synchronized boolean isStopped() {
return this.isStopped;
}
public synchronized void stop() {
this.isStopped = true;
try {
this.serverSocket.close();
}
catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
private void openServerSocket() {
try {
InetSocketAddress serverAddr = new InetSocketAddress(SERVERIP,
serverPort);
serverSocket = new ServerSocket();
serverSocket.bind(serverAddr);
} catch (IOException e) {
throw new RuntimeException("Cannot open port", e);
}
}
WHAT I don't understand:
I'm using a ThreadPooledServer which accepts for 5 incoming connections....
The connection with the clients is done in a while() loop.
while (!isStopped()) {
}
isStopped is a boolean variable returned byt this function:
private synchronized boolean isStopped() {
return this.isStopped;
}
which I call as a condition for starting the loop.
This boolean variable is initially set to false.....and is set back to true in the here:
public synchronized void stop() {
this.isStopped = true;
}
When is setup back to true my while() loop ends and then I close up all the workers of my thread pool.
this.threadPool.shutdown();
The problem is that I never call for this function " stop() "
Question: Is the function called automatically when I close my server?????...or I should call for it somewhere????
You need to call it somewhere in your code to stop your server and close those connections. If you don't the system will eventually reclaim its resources as the server will be shutting down.
You should be able to register a shutdown hook in the JVM (which can call stop()) to help with reclaiming those yourself... Good luck!

how to use notify and wait

Can wait/notify be used within one thread?
I'm mean I have a listener and in the moment when that listener gets called I wanna enable a thread to do his work.How could I do that?
UPDATE:My data is written in a database...and is written each time the listener is called.Now the thread that I've created reads that data and sends it somewhere....
Next...I get some other data and do the same thing....The other thread needs to know what was the last data he read it so he can start reading from where he left....
Take a look in here:
using wait and notify within one thread
This is how my problem looks like.Thx
I have the following:
synchronized (syncToken)
{
try {
syncToken.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyThread: " + s);
in MyThread....so when I do
MyThread t = new MyThread(syncToken);
t.start();
I put my thread on waiting...yes?
And when I do this:
syncToken.notify();
I get my thread back on track....but the execution of the next line is the one after wait()?
I mean this: System.out.println("MyThread: " + s); ????
When u notify a thred does he continues his execution with the line after wait()???Thx
The following is a simple example of concurrency between two different threads. In the example the main thread start a MyThread thread and every 3 seconds it sets a data to the MyThread instance and then MyThread prints it. The idea is to have a synchronized object that you wait on it and notify in the end of the usage to other threads that they can use it:
Test.java:
package stack;
public class Test {
public static void main (String args[])
{
Object syncToken = new Object();
MyThread t = new MyThread(syncToken);
t.start();
for (int i = 0; i < 10; i++)
{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(syncToken)
{
t.setText("Iteration " + i);
syncToken.notify();
}
}
}
}
MyThread.java:
package stack;
public class MyThread extends Thread{
String s;
Object syncToken;
public MyThread(Object syncToken)
{
this.s = "";
this.syncToken = syncToken;
}
public void run()
{
while(true) // you will need to set some condition if you want to stop the thread in a certain time...
{
synchronized (syncToken)
{
try {
syncToken.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyThread: " + s);
}
}
public void setText(String s)
{
this.s = s;
}
}
In this example, the main thread sets a string (every 3 seconds) and the MyThread thread prints it.
Adapt it to your needs, it shouldn't be too hard.
I had similar problem. I created an arbiter used by two threads (in your case it can be listeners thread and your task thread):
listener:
arbiter.waitConsumer();
// prepare data
arbiter.dataLoaded();
task thread:
while(true){
arbiter.waitProducer();
// consume data
arbiter.dataConsumed();
}
arbiter:
public class Arbiter {
private boolean dataLoaded = false;
public synchronized void waitProducer(){
while(!dataLoaded){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void waitConsumer(){
while(dataLoaded){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void dataLoaded(){
dataLoaded = true;
notify();
}public synchronized void dataConsumed(){
dataLoaded = false;
notify();
}}
Listener and task will synchronize themselfes against arbiters monitor. Probably you can call your arbiter queue or pipe and store date for consuming in it?

Categories

Resources