What exactly does the post method do?

Android

Android Problem Overview


I've encountered a very weird feature.

When I'm trying to run an animation on the main thread, it does not start. When I run said animation using

getView().post(new Runnable() {
			@Override
			public void run() {
				getView().startAnimation(a);
			}
		});

It does start.

I've printed the CurrentThread before starting the animation and both print main.

Obviously, I am missing something here, as both should start the animation on the main thread... My guess is that as post adds the task to the queue, it starts at a more "correct time", but I would love to know what happens here at more depth.

EDIT: Let me clear things up - my question is, why starting the animation on post causes it to start, when starting the animation on the main thread does not.

Android Solutions


Solution 1 - Android

post :post causes the Runnable to be added to the message queue,

Runnable : Represents a command that can be executed. Often used to run code in a different Thread.

run () : Starts executing the active part of the class' code. This method is called when a thread is started that has been created with a class which implements Runnable.

getView().post(new Runnable() {

         @Override
         public void run() {
             getView().startAnimation(a);
         }
     });

code : getView().startAnimation(a);

in your code,

post causes the Runnable (the code will be run a in different thread) to add the message queue.

So startAnimation will be fired in a new thread when it is fetched from the messageQueue

[EDIT 1]

Why do we use a new thread instead of UI thread (main thread)?

UI Thread :

  • When application is started, Ui Thread is created automatically

  • it is in charge of dispatching the events to the appropriate widgets and this includes the drawing events.

  • It is also the thread you interact with Android widgets with

> For instance, if you touch the a button on screen, the UI thread > dispatches the touch event to the widget which in turn sets its > pressed state and posts an invalidate request to the event queue. The > UI thread dequeues the request and notifies the widget to redraw > itself.

What happens if a user press a button which will do longOperation ?

((Button)findViewById(R.id.Button1)).setOnClickListener(           
             new OnClickListener() {		
        @Override
	public void onClick(View v) {
            final Bitmap b = loadImageFromNetwork();
            mImageView.setImageBitmap(b);
}
});

The UI freezes. The program may even crash.

public void onClick(View v) {
  new Thread(new Runnable() {
    public void run() {
        final Bitmap b = loadImageFromNetwork();
        mImageView.setImageBitmap(b);
    }
  }).start();
}

It breaks the android rule that never update UI directly from worker thread

Android offers several ways to access the UI thread from other threads.

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  • Handler

Like below,

View.post(Runnable)

public void onClick(View v) {
  new Thread(new Runnable() {
    public void run() {
      final Bitmap b = loadImageFromNetwork();
      mImageView.post(new Runnable() {
        public void run() {
          mImageView.setImageBitmap(b);
        }
      });
    }
  }).start();
}

Handler

final Handler myHandler = new Handler(Looper.getMainLooper());
				
(new Thread(new Runnable() {
					
	@Override
	public void run() {
	   final Bitmap b = loadImageFromNetwork();
   	  myHandler.post(new Runnable() {							

   	    @Override
	    public void run() {
	       mImageView.setImageBitmap(b);
	      }
	    });
	  }
	})).start();				
}

enter image description here

For more info

http://android-developers.blogspot.com/2009/05/painless-threading.html

http://www.aviyehuda.com/blog/2010/12/20/android-multithreading-in-a-ui-environment/

Solution 2 - Android

Is this being done on onCreate or onCreateView? If so, the app might not be in a state where the View is attached to the window. A lot of algorithms based on View metrics may not work since things like the View's measurements and position may have not been calculated. Android animations typically require them to run through UI math

View.post actually queues the animation on the View's message loop, so once the view gets attached to the window, it executes the animation instead of having it execute manually.

You are actually running things on the UI thread, but at a different time

Solution 3 - Android

Have a look here for a good answer. view.post() is the same as handler.post() pretty much. It goes into the main thread queue and gets executed after the other pending tasks are finished. If you call activity.runOnUiThread() it will be called immediately on the UI thread.

Solution 4 - Android

The problem I think could be the life-cycle method where you are calling the post() method. Are you doing it in onCreate()? if so look at what I found in the activity's onResume() documentation:

> onResume() > > Added in API level 1 void onResume () Called after > onRestoreInstanceState(Bundle), onRestart(), or onPause(), for your > activity to start interacting with the user. This is a good place to > begin animations, open exclusive-access devices (such as the > camera), etc.

https://developer.android.com/reference/android/app/Activity.html#onResume()

So, as Joe Plante said, maybe the view is not ready to start animations at the moment you call post(), so try moving it to onResume().

PD: Actually if you do move the code to onResume() then I think you can remove the post() call since you are already in the ui-thread and the view should be ready to start animations.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGalView Question on Stackoverflow
Solution 1 - AndroidTalhaView Answer on Stackoverflow
Solution 2 - AndroidJoe PlanteView Answer on Stackoverflow
Solution 3 - AndroidTas MorfView Answer on Stackoverflow
Solution 4 - AndroidcarrizoView Answer on Stackoverflow