2

I am trying to find a way to send a message from the a seperate thread to the UI Thread, is that possible? The thread has not been launched from the MainActivity but from a service, does it make any difference.

Thanks in advance for you help.

Here is the thread from where i would like to send the message i receive to the UI Thread

   import java.io.BufferedReader;
   import java.io.IOException;

   import android.os.Bundle;
   import android.os.Handler;
   import android.os.Message;
   import android.util.Log;

    public class Receive_Client implements Runnable {
    private BufferedReader in;
    private String message=null;

    // The Bundle will hold the String "Location or message" and will transmit it to the     handler in the mainActivity
      private String[] messageArray=new String[3];
      Bundle messageBundle=new Bundle();
    // corresponds to the message that will be exchange it with the UIThread Handler

     private Message Message;

  public Receive_Client(BufferedReader in) {
  this.in=in;


     }
@Override
public void run() {
    // If isRunning is at false the Thread have to stop
    while(isRunning.get()){// error here---------->
        try{
            while (isPausing.get() && (isRunning.get())) {//here also -------->
                // Pausing the Thread to relax the CPU 

                Thread.sleep(2000);
            }
            if ((message=in.readLine())!=null){
                //message=in.readLine();
                Log.d(MainActivity.TAG, "the server say"+message);
                // Sending the message to the Handle (the method handler.obtainMessage is more efficient
                // rather than using a message from zero, optimizing the message pool to the handler)
                // message instanciation
                messageArray=message.split(",");
                Message=handler.obtainMessage();    //---------> the handler also
                // Adding data to transmit to handler via Bundle

                messageBundle.putStringArray(RECEIVE_LOCATION, messageArray);// the key is not recognized too----->
               //adding the bundle to the message
                Message.setData(messageBundle);
                //send the message
                handler.sendMessage(Message);


            }
            }catch (IOException e){
                Log.d(MainActivity.TAG, e.getMessage());}

            }


    }

    }
user3141990
  • 129
  • 1
  • 7

4 Answers4

1

You will have some code like this anywhere you want: service, activity, etc. (this is a Context):

LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
Intent i = new Intent(REFRESH_CONSTANT);
lbm.sendBroadcast(i);

Then in your UI you listen for this broadcast:

public class MyFragment extends Fragment {

    MyReceiver r;

    public void refresh() {
        // Do the refresh
    }

    public void onPause() {
        LocalBroadcastManager.getInstance(mContext).unregisterReceiver(r);
    }

    public void onResume() {
        r = new MyReceiver ();
        LocalBroadcastManager.getInstance(mContext).registerReceiver(r,
            new IntentFilter(REFRESH_CONSTANT));
    }

    private class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            MyFragment.this.refresh();
        }
    }
}

You can put more data in the intent object as needed.

doorstuck
  • 2,299
  • 1
  • 22
  • 29
  • But the code that i am running is in a seperate thread, should i use runOnUIThread() or a broadcast receiver. Do i have the right to have an Intent in a thread? – user3141990 Jan 09 '14 at 20:26
  • Sending the broadcast does not need to happen on the UI thread. It rarely will. So do not use runOnUIThread(). Just make sure you have a reference to the Context inside your Thread (pass it in the constructor and save it as a field for example). – doorstuck Jan 09 '14 at 20:46
0

What you want to use is a handler. You can use these objects to send messages in between different threads. A handler will receive messages for the thread that it was instantiated in. Therefore, create a handler for each thread and then implement the appropriate callbacks.

http://developer.android.com/reference/android/os/Handler.html

Andre Perkins
  • 7,640
  • 6
  • 25
  • 39
  • How can the Working thread send the message to the Handler in the case that the Working thread is launched from another Service? – user3141990 Jan 09 '14 at 22:31
  • The handler created in the second thread would just need a reference to the one created in the main thread. There are a variety of ways to do that, the simplest would be to pass the main thread's handler reference to the service that is creating the second thread. – Andre Perkins Jan 09 '14 at 22:42
  • I am not sure to understand correctly your answer. Can you detail please? – user3141990 Jan 09 '14 at 22:47
  • Is the the service being started (or binded to) in MainActivity that you want the messages to be sent to? If so, then you can just pass the handler directly to the service through a function and then when you create the second thread, you take the handler from the service nand make calls on it. – Andre Perkins Jan 09 '14 at 23:01
  • The service is Binded to the MainActivity – user3141990 Jan 09 '14 at 23:05
  • i have also AtomicBoolean in the MainActivity how can i access to them from the thread in order to pause and stop the Working thread according the Lifecycle of the MainActivity? Can't stop asking questions :) – user3141990 Jan 09 '14 at 23:13
  • I think you can just pass the object as a reference, just like the Handler. Although, you would have to worry about threding and concurrency issues. I would try it out but I am on my phone. Let me know how it goes. – Andre Perkins Jan 10 '14 at 00:22
  • Hi, I am still stacked with this issue, i don't know how to do? i will update my post so that you can see my code. But actually the handler and the Atomic Booleans isRunning and isPausing are not recognized :/ – user3141990 Jan 10 '14 at 17:05
  • I am unsure where you are declaring or instantiating your isRunning and isPausing objects. I assume that these are the atomic variables from your MainActivity class. If that is the case, you can pass them to thread the same way that you are passing the in (BufferReader) object. – Andre Perkins Jan 10 '14 at 19:35
  • if i call them by MainActivity.handler MainActivity.isRunning.. would it be problematic ? – user3141990 Jan 11 '14 at 13:48
  • If the the handler and atomic variable are class (static) and final variables, then that should work. – Andre Perkins Jan 11 '14 at 16:51
  • So it's not helping since the value of the handler and the Atomicbooleans are meant to change :/. – user3141990 Jan 11 '14 at 21:40
  • Then you can just create getter functions for the variables in the MainActicity class and call the getter methods to obtain the references instead of trying to access the fields directly. – Andre Perkins Jan 12 '14 at 21:18
  • Thanks a lot, actually i tried to create a class extending Application and i put the global variables in order to be able to access to them from different services and also from the Threads. But for the handler i still have some problem and until now i don't really know how to make it – user3141990 Jan 13 '14 at 22:44
  • Creating the handler is a simple as creating any object. Create on handler in your MainActivity class and then store – Andre Perkins Jan 14 '14 at 20:18
  • Create a handler in your MainActivity class and then store the reference to this object wherever you are storing the other objects that persist between different activities. Then you create another handler in the thread's execution code. Then have the thread's handler reference stored somewhere where the MainActivity will have access to it. Then you can just send messages to the other thread by using the sendMessage on the handler. This is all confusing, if you are still struggling with this, I can put together a blog post if you think that might help? – Andre Perkins Jan 14 '14 at 20:32
0

Look for worker thread in below link also post and postdelayed.

worker thread

Prachur
  • 1,100
  • 7
  • 24
  • 42
  • I have the same question for you, How can the Working thread send the message to the UI thread Handler in the case that the Working thread is launched from another Service? – user3141990 Jan 09 '14 at 22:33
0

Try to use EventBus. For me is the best way to to communicate between Services, Fragments and Activities. You can also send messages from background thread to ui thread.

Piotr Ślesarew
  • 2,826
  • 1
  • 17
  • 17