Why would i want to use runOnUiThread ???

This is part of the code from my AndroidLauncher.
I got it from a tutorial from in the libgdx documentation on using AdMob :

@Override
	public void showBannerAd() {
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				bannerAd.setVisibility(View.VISIBLE);
				AdRequest.Builder builder = new AdRequest.Builder();
				AdRequest ad = builder.build();
				bannerAd.loadAd(ad);
			}
		});
	}

First I though runOnUiThread would create e separate thread to handle the adRequest, but when I read up on what
the UI Thread actually is, I read it’s the main thread and it’s the same one that the code for my game would be running on.

If that’s the case then why would that piece of code be in there (can I leave it out)? Or does it maybe has something to do with that when I want to access this method from within my game classes I’m doing that via an interface?

Because everything you do to change UI should be done on UI thread, so undefined stuff doesn’t happen.

The UI thread is not the main thread. It’s an Android thread, separate from the OGL thread libgdx is running (or any threads you created that might call showBannerAd()).

https://code.google.com/p/libgdx-users/wiki/IntegratingAndroidNativeUiElements

EDIT: seems Android call’s it’s UI thread “main.” Here by main I mean your libgdx thread.

But google documentation says that the standard (main) thread to run my game on is the UI Thread. Thus by definition - correct me if i am wrong - if I would run this it should already be allocated to run on the ui thread. Doesnt make sense to me yet why i have to declare it specifically here

http://developer.android.com/guide/components/processes-and-threads.html

edit*

[quote]As such, the main thread is also sometimes called the UI thread.
[/quote]

@ burntpizza: posted my message same time as yours

Now I C.

thanks

TrollWarrior pretty much covered it: updates to the GUI have to be made on the GUI thread, otherwise weird things happen.

But to demonstrate why that’s the case, here’s an example. Let’s say you display an image on the GUI thread, but have another thread that loads a new image to display. Something like this:


//gui thread
displayImage(image);

//loading thread
Image newImage = loadImage("path");
image = newImage;

The problem with this is, you can get into a situation where the GUI thread has already painted half of the image, but then the loading thread kicks in an modifies the image. Now the GUI thread will continue drawing the image, but the second half that it paints will come from the new image! So you’ll paint half of the first image and half of the second image, instead of only painting one image at a time.

To prevent that, you have to modify the image on the GUI thread:


//gui thread
displayImage(image);

//loading thread
Image newImage = loadImage("path");
doOnGuiThread(image = newImage;}

Now, the image will not change until after the GUI thread is done drawing the image, and next time the GUI thread fires (like in a game loop), the correct image will display. You still keep the loading off of the GUI thread, but the actual modification is on the GUI thread.

This is a bit of a contrived example, but hopefully it demonstrates what is meant by “weird stuff can happen”.

This is also the basic use of locks:


//gui thread
synchronized(image) {
    displayImage(image);
}

//loading thread
synchronized(image) {
    Image newImage = loadImage("path");
    image = newImage;
}

(Note: contrived example, I don’t think it would run, needs a separate lock object)

Now only one of the two threads can be “using” image at a time, and no weird things happen.
Well, at least until you get threads waiting on each other (deadlock), or something more complicated than unordered access of a single variable.

True. But you don’t want to use locks on the UI thread, since you want it to always be running. This is why we usually put stuff on the UI thread instead of worrying about thread safety.

Very true.
Although I’d say shunting closures is worrying about thread safety. :wink: