Reputation: 29
I am trying to receive serial data from Arduino and i want to store the value in a variable how can i do it ? I tried the code below but it is not storing the value of string in the array element t[0]
or is there a way to store reading from input stream ?
final String[] t = new String[1];
t[0]="0";
final Handler handler = new Handler();
stopThread = false;
buffer = new byte[1024];
Thread thread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopThread)
{
try
{
int byteCount = inputStream.available();
if(byteCount > 0)
{
byte[] rawBytes = new byte[byteCount];
inputStream.read(rawBytes);
final String string=new String(rawBytes,"UTF-8");
handler.post(new Runnable() {
public void run()
{
textView.append(string);
t[0]=string;
}
});
}
}
catch (IOException ex)
{
stopThread = true;
}
}
}
});
thread.start();
return t[0];
Upvotes: 2
Views: 6825
Reputation: 7325
You are setting the value of t[0]
inside a new Thread which will run asynchronously. So it is possible that return t[0];
execute before another thread set the value of t[0]. You can use Thread#join
write the code as below.
thread.start();
thread.join();
return t[0];
When you call Thread#join
the parent thread will wait to finish the Thread
on which you have called the join
method.
However, there are several mechanisms to do that like CountDownLatch
and CyclicBarrier
or Future
but I think Thread#join is the easy and best suited for your use case.
Upvotes: 0
Reputation: 1029
In addition to TMH's answer, if you want to manage threads yourself or suggested code seems too complicated for now, here's a simpler way of using CompletableFuture:
CompletableFuture<Object> completableFuture = new CompletableFuture<>();
new Thread(new Runnable() {
@Override
public void run() {
// computation, reading input streams, etc
Object result = new Object();
completableFuture.complete(result);
}
}).start();
// get() will wait until it's completed
Object resultFromThread = completableFuture.get();
// further processing...
Upvotes: 3
Reputation: 671
Maybe better solution will be something like this:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class ResultFromThread {
public static void main(String... args) throws ExecutionException, InterruptedException {
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
return "something";
});
String result = cf.get();
}
}
Instead of 'return "something";' you just need to add anything you want to do.
Another solution is (with handling an exception):
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class ResultFromThread {
public static void main(String... args) throws ExecutionException, InterruptedException {
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
return "something";//may also throw an exception
}).handle((result, throwable) -> {
if(throwable != null) {
System.err.println(throwable);//do something with exception
}
return result;
});
String result = cf.get();
}
}
Upvotes: 2