0

This is not the problem about being able to call a method in the main/UI thread but being able to do so instantaneously.

It is my knowledge that you are not normally allowed to interact with the UI thread directly because of the UI responsive requirements. It would make sense then to have a system in place to queue the requests you have for the main thread and we do have that system with the looper, handler, etc.

Here is what I did: I did some task in the background thread and I want to intimate the main thread as soon as a condition gets satisfied(I created a listener for it) and I use the response handler to post it..something like this:

if(mNoOfPendingRequests >= mNoOfRequestsConsideredEnough){
            mShouldFlagEnoughRequestsAtATime = true;
            Log.i("ThumbnailDownloader: ","Enough Requests Queued");
            //Now inform about this to PhotoGallery right now
            mResponseHandler.postAtFrontOfQueue(new Runnable() {
                public void run() {
                    mEnoughRequestsListener.onEnoughRequestsQueued(mShouldFlagEnoughRequestsAtATime);
                }
            });
        }
        else{
            mShouldFlagEnoughRequestsAtATime = false;
            mEnoughRequestsListener.onEnoughRequestsQueued(mShouldFlagEnoughRequestsAtATime);
        }

If I don't inform the PhotoGallery about the enough requests sent already, it would continue to send more and more requests and app becomes unresponsive.

Also, the requests are queued and are executed later resulting in too many requests.

My question is therefore:

Is there a way to call a method/inform in UI thread from a background thread almost instantaneously?

Manish Kumar Sharma
  • 12,982
  • 9
  • 58
  • 105

5 Answers5

1

You can run things on UI thread doing this:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        // put your code here :)
    }
});
Augusto Carmo
  • 4,386
  • 2
  • 28
  • 61
1

Is there a way to call a method/inform in UI thread from a background thread almost instantaneously?

Not really. Your postAtFrontOfQueue() is about as close as you can get, and as the boldface note mentions in the docs, "This method is only for use in very special circumstances -- it can easily starve the message queue, cause ordering problems, or have other unexpected side-effects."

If I don't inform the PhotoGallery about the enough requests sent already, it would continue to send more and more requests and app becomes unresponsive. Also, the requests are queued and are executed later resulting in too many requests.

Have more smarts in your queue, to know when to throttle back request processing based upon whatever your "enough" algorithm is.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Reading what you said and what I had been speculating...If there was a way to execute tasks on the main thread instantaneously, it would definitely get misused by people like "me". Not too surprising being unable to find a way. Anyway, thanks for the response. – Manish Kumar Sharma Aug 27 '16 at 18:51
  • 1
    Be careful of postAtFrontOfQueue on the UI thread! It can starve it as easily as a long running task. – G. Blake Meike Aug 27 '16 at 23:13
0

This method works like a charm unless you already have lots of events in your events queue.
activity.runOnUiThread(new Runnable() { public void run() { // call your method here } });

iamabhaykmr
  • 1,803
  • 3
  • 24
  • 49
0

Yes, you can call using activity context

runOnUiThread() and pass runnable object and write code inside run() method.

Yogesh Rathi
  • 6,331
  • 4
  • 51
  • 81
0

It is not clear from your code, what onEnoughRequestsQueued does. If all it is doing is telling the posting thread that it should stop sending requests, then you can probably accomplish the same thing with a simple volatile boolean

If the thread enqueuing requests stops doing so, when the variable is true, and the background thread sets it true, and the variable is volatile you should be good.

G. Blake Meike
  • 6,615
  • 3
  • 24
  • 40