1

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];
Würgspaß
  • 4,660
  • 2
  • 25
  • 41
Lama
  • 19
  • 1
  • 2
  • Check [this](https://stackoverflow.com/a/9148992/9441307) might help, it uses callable to return value from the executed threads. For more information about callable check [this](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html). – Akhadra Apr 23 '18 at 08:20

3 Answers3

2

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...
Cargeh
  • 1,029
  • 9
  • 18
1

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();
    }
}
THM
  • 579
  • 6
  • 25
0

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.

Amit Bera
  • 7,075
  • 1
  • 19
  • 42