Advice on Android Thread - java

Good day and I am here to take some advice from you. Basically I have a class that has two methods as follows. It allows me to send data to the serial port (UART) and I receive data from it. Works fine.
Now, I have to modify it in such a way that it will send some data to the serial port serialPort.writeBytes(src.getBytes()); and wait for the reply for 3 seconds, if I get a reply in between 3 seconds it has to be updated to a TextView and if not it has to send the second data (serialPort.writeBytes(src1.getBytes());)and again wait for the reply.
I am not an expert in Threads and Handlers as I have just started to learn it. Please advise me on this. Thank you very much for your time.
public void sendData(){
final String src = "MYDATA\r";
final String src1 = "MYDATA1\r";
serialPort.writeBytes(src.getBytes());
**// Pause here and wait for the reply**
serialPort.writeBytes(src1.getBytes());
**// Pause here and wait for reply**
}
private class ReadThread extends Thread {
byte[] buf = new byte[512];
#Override
public void run() {
super.run();
while (!isInterrupted()) {
int size;
if (mInputStream == null)
return;
size = serialPort.readBytes(buf);
if (size > 0) {
byte[] dest = new byte[size];
System.arraycopy(buf, 0, dest, 0, size);
byteLinkedList.offer(dest);
onDataReceived();
}
}
}
}
Now

This is not an answer, I cant comment cause I don't have enough rep.
I agree with momo. So you will have something like this:
class SendThread extends Thread{
boolean gotData = false; //flag to check if data is received.
#Override
public void run(){
while(gotData == false){
new Runnable() {
#Override
public void run(){
//SendData code
//if you get Data change gotData = true;
}
}.run();
Thread.sleep(3000); //sleep for 3 secs
}
}
}

If you don't have a complex situation, you can use the Android AsyncTask - do a search and you will find a lot of references to it.
Essentially, you need an interface that you can call to respond when the data is received. Polling is a matter of calling wait on this thread. If you are not familiar with wait, you can also search easily for it.
The key issue is that the UI should not wait and with a thread or AsyncTask it will not.
If you decide to use threads, then look into creating a simple "listener" (aka interface). It might seem intimidating, but basically it is an empty class that you will need to pass into your custom thread.
Also, you may need to consider if your Activity will still be visible during this process. If it might not be, and you still need to complete the task in the background, you will need a Service
This is a good "overview" of your options: http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
Since you really haven't defined the full use-case, you probably need to do more research or be more specific. But this should get you going in the right direction.

Related

How return a result of my method executed in thread?

I've a method who return a result (return an integer), my method is executed in a Thread for load 40 000 objects, i return an integer who count the number objects loaded. My question is, How return the int with the Thread ? Actually, the result is returned directly and is equal to 0.
public int ajouter(params) throws DaoException, ConnectException {
final ProgressDialog dialog = ProgressDialog.show(mActivity, "Title",
"Message", true);
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
dialog.dismiss();
}
};
Thread t = new Thread() {
public void run() {
try {
Str_Requete = "SELECT * FROM Mytable";
ResultSet result = ExecuteQuery(Str_Base, Str_Requete);
Index = addObjects(result);
handler.sendEmptyMessage(0);
} catch (SQLException e) {
e.printStackTrace();
}
}
};
t.start();
return Index;
}
When i call my method in my mainActivity :
int test = myObjs.ajouter(params);
test is equal to 0, the value is returned directly...
My constraint is didnt use AsyncTask.
The whole point of using a Thread is not to block the calling code while performing the task of the thread. Thread.start() returns immediately, but in the meantime a new thread is started in parallel to the current thread which will execute the code in the run() method.
So by definition there is no such thing as returning a value from a thread execution. You have to somehow send a signal back from the thread that performed the task to the thread in which you need the result. There are many ways of doing this, there's the standard Java wait/notify methods, there is the Java concurrency library etc.
Since this is Android, and I assume your calling code is running on the main thread, it's probably wise to use the functionality of Handler. And in fact, you are already doing that - you have a Handler that closes the dialog when the thread is done with its work - but for some reason you seem to expect the result of that work to be ready before it has even started. It would be reasonable to extend your existing Handler with some code that does something with the calculated value and remove the code that returns the value of a variable before or at the same time as it's being calculated by another thread.
I also strongly encourage you to study some concurrency tutorial such as Oracle's concurrency lesson or Android Thread guidelines to really understand what's going on in the background. Writing concurrent code without mastering the concepts is bound to fail sooner or later, because it's in the nature of concurrency that multiple things are happening at the same time, will finish in random order etc. It may not fail often, but you will go crazy wondering why something that works 90% of the time suddenly fails. That's why topics such as atomicity, thread synchronization etc are critical to comprehend.
Edit: Simple Android example of starting a worker thread, performing some work, posting back event to main thread.
public class MyActivity extends Activity {
private Handler mHandler = new Handler();
...
private void doSomeWorkInBackground() {
new Thread() {
public void run() {
// do slow work, this may be blocking
mHandler.post(new Runnable() {
public void run() {
// this code will run on main thread,
// updating your UI or whatever you need.
// Hence, code here must NOT be blocking.
}
});
}
}.start();
// This code will be executed immediately on the main thread, and main thread will not be blocked
}
You could in this example also use Activity.runOnUiThread(Runnable).
Please consider however that AsyncTask basically wraps this kind of functionality in a very convenient way, so if it suits your purposes you should consider using AsyncTask.
If you dont want to use AsyncTask or ForkJoin, then you could implement an Interface e.g. callback in your main class.
In your Example you dont wait until the Thread is done... thread.join
One Solution:
Your Thread is a extra class with an constructor to hold the reference to the calling class.
public Interface callback
{
public int done();
}
public class main implements callback
{
...
CustomThread t = new CustomThread(this)
...
}
public class CustomThread extends Thread
{
private Callback cb;
public CustomThread(Callback cb)
{
this.cb=cb;
}
.
.
.
//when done
cb.done(int)
}

Thread stops itself

I've been searching for a solution for a long time, but I wasn't able to find one, so I'll ask my question here.
I have a thread which is started when the program starts and supposed to be idle until it is enabled by the application. Simple code example:
private class UpdaterThread extends Thread {
private static final int UPDATE_RATE = 50;
private Timer updateTimer = new Timer();
private boolean enabled;
public void run() {
while (!closeRequested) {
// If this is uncommented, the thread works as it's supposed to.
// System.out.print("");
if (enabled) {
Snapshot next = getNextSnapshot(1f / UPDATE_RATE);
System.out.println("Got next Snapshot");
updateTimer.sync(UPDATE_RATE);
System.out.println("Push");
currentSnapshot = next;
}
}
}
public void enable() {
enabled = true;
}
public void disable() {
enabled = false;
}
}
When you read a variable, which the JIT believes you didn't modify, it inlines the value. If you then modify the value later, it is too late, the value has been embedded in the code.
A simple way to avoid this is to use volatile but you would still have the problem than the thread is busy waiting for the value to change and there doesn't appear to be a good reason to do this. Another option is to add code which confuses the JIT do it doesn't do this optimisation. An empty synchronized block is enough but a friendlier way is to use Thread.sleep() which at least doesn't use up all your CPU.
I suggest using a volatile fields and sleeping with a period of 10-100 ms. However a simpler option is to not start the thread until it is needed.
since run() is called when the thread is started, you could just wait until later in the program to start it, also threads do not extend "Thread" but implements "Runnable" so the class definition would look like:
public class UpdaterThread implements Runnable
hope it helps :D

Android TextView not fully updating

I have a thread which updates a textview using a runnable:
// runnable to allow updating the UI from the thread
Runnable updateTextView = new Runnable() {
public void run() {
mTextView.setText(mDisplayedText);
mTextView.invalidate();
}
};
However, the text does not update properly. It works for the first few writes, then only writes half the text, leaving the second half of the previous text there.
Turning the screen around causes it to refresh and draws it correctly.
The textview is multiline and I write a string to it which contains \n characters for the end of lines.
The invalidate call above makes no difference.
Any ideas?
UPDATE: mDisplayedText is declared in the activity which also contains my thread class. in the thread run loop, I call:
mDisplayedText = getText()
runOnUiThread(updateTextView);
The loop contains a 100ms sleep, but it only writes to the text when it has changed so in reality it will be less than once a second
ANSWER:
Slightly embarrassing this. The problem was in other code.
I was receiving a UDP socket into the same packet, and reading the packet.getData into a new string.
This was copying the whole packet into the string, rather than just the bytes received in that message.
The second problem was that I needed to call packet.setLength each time to set the length available to the whole packet.
Thanks for the answers!
you can only update your UI on UI thread, put your setText() method inside this
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText(someValue);
}
});
Runnable is an interface. Think of it like a set of commands ready for execution. You can use a Handler to work with your code:
Handler textViewHandler = new Handler();
// runnable to allow updating the UI from the thread
Runnable updateTextView = new Runnable() {
public void run() {
mTextView.setText(mDisplayedText);
}
};
textViewHandler.post(updateTextView);
Also, please consider #Karakuri's suggestion.

Android: Thread Runnable and Handler.post issues - (Handler.postXX does not run on time when expected) within the Run method

I have a TCP Socket used as a TCP client which is used to read incoming data from a server constantly -- until the client or the server drops the connection. I don't know of any other way but use a while (true) loop in a different Runnable thread and in it (in the while loop) check for incoming data. The received data needs to be printed in an EditText.
The problem I am having is updating the text from Handler.post(...).
I know that:
In order to create TCP connections with Android 3.0 and above, I am required to place the TCP code either in a new Thread(...) or an AsyncTask because Strict mode has been enabled by default and I do not want to disable it.
I know that in order to update the UI from a new Thread in Android, I need to use Handler.post() if I use a Thread or the onProgressUpdate via publichProgress if I use AsyncTask and I know how to use all these but I am experiencing weird frustrating issues with both of them.
So, all I want to do is:
Listen to the server permanently
As soon as the server sends me a message, example: 'w' or 'a' or n', I immidiately display it on the EditText. You can think of it as a telnet session but I need "more"
precision than telnet as I want to process every single byte, even non-printable ones so I do not want to use readLine in anyway. I must read a byte at a time OR get a buffer of bytes and then process them separately by iterating through the buffer. I went with a byte at a time.
Here is the code I have and please pay attention to my comment above handle.response to see the problem I am having. I hope you can clear this out.
The code is very briefly coded and I have removed a lot of the error checking sections for this sample.
I have a new class called: ThreadClientInput:
public class ThreadClientInput implements Runnable {
InputStream inputStream;
MainActivity mainActivity;
Handler handler = new Handler();
int NextByte = 0;
public ThreadClientInput(MainActivity ma)
{
mainActivity = ma;
}
#Override
public void run()
{
////////////////////////////////////////////////////////////////
// Run the sensitive code that requires us to create this thread
try {
mainActivity.tcp_Client = new Socket("192.168.1.90", 23);
}
catch (Exception e){Log.e("EXEPTION:", e.getMessage().toString());return;}
////////////////////////////////////////////////////////////////
// Only try to get the inputStream if we have a successful connection
if (mainActivity.tcp_Client != null)
{
try
{
inputStream = mainActivity.tcp_Client.getInputStream();
}
catch (Exception e){Log.e("EXEPTION:", e.getMessage().toString()); return;}
}
/////////////////////////////////////////////
/////////////////////////////////////////////
// Update the text on the "Connect" button
handler.post(new Runnable()
{
#Override
public void run()
{ mainActivity.btn_Connect.setText("Connected");}
});
/////////////////////////////////////////////
/////////////////////////////////////////////
try
{
// I need to constantly read the data until we manually disconnect or
// the server drops the connection
while (true)
{
// Get the next byte
// I do not want to use "readline()" from a BufferedReader etc because I need to know exactly what's coming in
// I need to process every single byte
NextByte = inputStream.read();
if (NextByte > -1)
{
Log.e("in (While loop):", Character.toString((char)NextByte));
*** Here is the problem ****
// Update the EditText and this is where the problem starts
// if the server sends "1234", the Log.e() above will display everything correctly: "1234"
// however the handler.post below will run at the end of the last byte so the
// the EditText as well as the second Log.e below within the handle.post will display: "1444" or "4444" or "2444"
// So the handler.post does *not* run immediately even if I try handle.postAtFrontOfQueue()
// If the server sends "12345678", again, Log.e() above will display everything correctly: "12345678"
// however the handler.post below will run at the end of the last byte again
// and I will get "88888888" (most of the time) or "18888888"
//
handler.post(new Runnable()
{
#Override
public void run()
{
mainActivity.et_Response.setText(mainActivity.et_Response.getText() + Character.toString((char)NextByte));
Log.e("In handler.post:", Character.toString((char)NextByte));
}
});
}
}
}
catch (Exception e){Log.e("EXEPTION:", e.getMessage().toString());}
}}
I tried various variations including one with runOnUiThread and AsyncTask, with all I am getting same results. I am out, I have nothing. At this point of time I am just reading some documentation about Handle.post method to see if I can make sense.
I hope you have a solution and I know that "while (true)" isn't a good practice but I can break the loop from outside the thread with setting a flag and I don't know of any other way how to do this.
I am not sure how you are able to access NextByte from public void run() without defining it as final !?
If you want the handler to post message to the Activity UI thread, yo should create it within the activity class so it can access its Looper.
I can think of two solutions for your problem as follows:
1- To use a custom Runnable class where you pass to it the NextByte value as variable e.g.
handler.post(new MyRunnable(NextByte));
And MyRunnable can be something like:
class MyRunnable implements Runnable{
int byteData;
public MyRunnable(int byteData){
this.byteData = byteData;
}
public void run(){ // update the EditText}
}
2- To use handler.sendMessage(); and add the NextByte as the message argument e.g.
Message msg = new Message();
msg.arg1 = NextBye
handler.sendMessage(msg);
And your handler should be defined as following:
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
int nextByte = msg.arg1;
// update the EditText
}
};
Problem has been resolved.
This is what I did this.
In MainActivity.java which is the main file, in class MainActivity
public static class MyRunnable implements Runnable {
int currentByte = 0;
public MyRunnable(int b){
currentByte = b;
}
#Override
public void run()
{
mainActivity.et_Response.setText(mainActivity.et_Response.getText() + Character.toString((char)currentByte));
}
}
I have a statement mainActivity = this; in onCreate and then in ThreadClientInput.run
try {
while (true)
{
NextByte = inputStream.read();
// if the server drops the connection, break out the loop
if (NextByte < 0) break;
handler.post(new MainActivity.MyRunnable(NextByte));
}
}
catch (Exception e) {
Log.e("EXCEPTION", e.getMessage());
}
After this, handler.post is getting called correctly and at the correct and expected time. Full credit goes to iTech.

What is the correct way to pass data to a running thread

In most cases when you create your thread you can prepare the data beforehand and pass it into the constructor or method.
However in cases like an open socket connection you will typically already have a thread created but wish to tell it to perform some action.
Basic idea:
C#
private Thread _MyThread = new Thread(MyMethod);
this._MyThread.Start(param);
Java
private Thread _MyThread = new Thread(new MyRunnableClass(param));
this._MyThread.start();
Now what?
So what is the correct way to pass data to a running thread in C# and Java?
One way to pass data to a running thread is by implementing Message Queues. The thread that wants to tell the listening thread to do something would add an item to the queue of the listening thread. The listening thread reads from this thread in a blocking fashion. Causing it to wait when there are no actions to perform. Whenever another thread puts a message in the queue it will fetch the message, depending on the item and it's content you can then do something with it.
This is some Java / pseudo code:
class Listener
{
private Queue queue;
public SendMessage(Message m)
{
// This will be executed in the calling thread.
// The locking will be done either in this function or in the Add below
// depending on your Queue implementation.
synchronize(this.queue)
{
this.queue.put(m);
}
}
public Loop()
{
// This function should be called from the Listener thread.
while(true)
{
Message m = this.queue.take();
doAction(m);
}
}
public doAction(Message m)
{
if (m is StopMessage)
{
...
}
}
}
And the caller:
class Caller
{
private Listener listener;
LetItStop()
{
listener.SendMessage(new StopMessage());
}
}
Of course, there are a lot of best practices when programming paralllel/concurrent code. For example, instead of while(true) you should at the least add a field like run :: Bool that you can set to false when you receive a StopMessage. Depending on the language in which you want to implement this you will have other primitives and behaviour to deal with.
In Java for example you might want to use the java.util.Concurrent package to keep things simple for you.
Java
You could basically have a LinkedList (a LIFO) and proceed (with something) like this (untested) :
class MyRunnable<T> implements Runnable {
private LinkedList<T> queue;
private boolean stopped;
public MyRunnable(LinkedList<T> queue) {
this.queue = queue;
this.stopped = false;
}
public void stopRunning() {
stopped = true;
synchronized (queue) {
queue.notifyAll();
}
}
public void run() {
T current;
while (!stopped) {
synchronized (queue) {
queue.wait();
}
if (queue.isEmpty()) {
try { Thread.sleep(1); } catch (InterruptedException e) {}
} else {
current = queue.removeFirst();
// do something with the data from the queue
}
Thread.yield();
}
}
}
As you keep a reference to the instance of the LinkedList given in argument, somewhere else, all you have to do is :
synchronized (queue) {
queue.addLast(T); // add your T element here. You could even handle some
// sort of priority queue by adding at a given index
queue.notifyAll();
}
Edit: Misread question,
C#
What I normally do is create a Global Static Class and then set the values there. That way you can access it from both threads. Not sure if this is the preferred method and there could be cases where locking occurs (correct me if I'm wrong) which should be handled.
I haven't tried it but It should work for for the threadpool/backgroundworker as well.
One way I can think of is through property files.
Well, it depends a lot on the work that the thread is supposed to do.
For example, you can have a thread waiting for a Event (e.g. ManualResetEvent) and a shared queue where you put work items (can be data structures to be processed, or more clever commands following a Command pattern). Somebody adds new work to the queue ad signals the event, so the trhread awakes, gets work from the queue and start performing its task.
You can encapsulate this code inside a custom queue, where any thread that calls the Deque methods stops until somebody calls Add(item).
On the other hand, maybe you want to rely on .NET ThreadPool class to issue tasks to execute by the threads on the pool.
Does this example help a bit?
You can use delegate pattern where child threads subscribes to an event and main thread raises an event, passing the parameters.
You could run your worker thread within a loop (if that makes sense for your requirement) and check a flag on each execution of the loop. The flag would be set by the other thread to signal the worker thread that some state had changed, it could also set a field at the same time to pass the new state.
Additionally, you could use monitor.wait and monitor.pulse to signal the state changes between the threads.
Obviously, the above would need synchronization.

Categories