Is it necessary to call Looper.prepare() from within the UI thread? - android

If I want to implement a Handler object from within my Activity's main thread, do I need to call Looper.prepare() beforehand, or do activities already have their own internal loopers? Does the same hold true if I want to instantiate a Handler instance from within a Service?

The main thread already has its own looper. See Context.getMainLooper(). The main thread encompasses all Activities and Services in the application.

Related

Can a background thread trigger a message handler on UI thread in android

I have a thread which is started in onCreate() and this thread fetches some data.
Is it possible that before the thread is terminated should be able to update the ListView?
Now as the thread is not the UI thread, it cannot directly update the listview array adapter.
Is there a way out?
I was thinking that is it possible to trigger a Handler from thread whose runnable gets executed on main UI thread.
Not sure if I understood your problem completely, but I believe there are two ways to achieve what you want:
1- Start an AsyncTask instead of a thread. AsyncTask's onPostExecute() will run in the UI thread, which means you can do anything UI-related in there. You can start the AsyncTask in onCreate(), and, once it finished, it calls a method on your activity which does:
myAdapter.notifyDataSetChanged();
2- Use runOnUIThread()
Use your Activity's runOnUiThread(Runnable action)
link

Android, Instantiating Instance Variables, What Thread?

All:
I am studying code that has a handler that is declared and instantiated along with other instance variables:
public class SomeActivity extends Activity {
Handler handler = new Handler(); // What thread is this taking place on?
// rest of class omitted
}
so is it being instantiated on the UI thread? I hope so, because it is used to post a Runnable to a ProgressBar, and my understanding is that the ProgressBar should only be manipulated on the UI Thread.
The Android docs say that something created in onCreate() is:
An application's activities run on the application's UI thread. Once
the UI is instantiated, for example in the activity's onCreate()
method, then all interactions with the UI must run in the UI thread."
but this is happening before onCreate().
Thanks for any info,
Michael
so is it being instantiated on the UI thread?
Yes. A Handler will exist in the Thread where it is created. You are creating yours on the main / UI Thread, so it can access UI elements.
but this is happening before onCreate().
This won't effect which Thread the Handler runs on.
Everything happens on the main thread (aka UI thread) unless you specifically run it on a background thread. So, yes, your Handler is created in the UI thread.

Why should some methods be invoked only from the main application thread?

I read about this class:
Do not instantiate this class directly, instead, call
createSpeechRecognizer(Context). This class's methods must be invoked
only from the main application thread.
I suppose that the main application thread is the main Activity of an Android application...
Why should this class's methods be invoked only from the main application thread?
The main application thread is also known as the UI thread.
This is done to ensure thread safety. (No two processes can modify the same value at the same time).
Please see: Why can only the UI thread in Android update the UI?

Android: difference between getMainLooper() and Looper.myLooper()

I'm now trying to resurrect one project.
There was an exception on getMainLooper()...
I thought that may be there's a problem with MainLooper initialization and added Looper.prepareMainLoop() before that.
Exception telling me that there's already a looper for that object was thrown...
Then I tried to replace getMainLooper() with Looper.myLooper() and it worked...
But I didn't understand why=)
In fact I don't get the difference between this two things. I think that on the place where getMainLooper() was used in my project it's the best place for the true main looper of the application but I got what I got..
Please explain.
Thank you for your attention
The difference is that Looper.prepareMainLooper() prepares looper in main UI thread. Android applications normally do not call this function. As main thread has its looper prepared long before first activity, service, provider or broadcast receiver is started.
But Looper.prepare() prepares Looper in current thread. After this function is called, thread can call Looper.loop() to start processing messages with Handlers.
So, in your case you had two threads - X and Y. The X thread is the main UI thread that has its looper already prepared by Android. When you are in Y thread and you're calling Looper.prepareMainLooper() you're trying to prepare looper in X thread (main thread). This fails because X's looper is already prepared. But when you call Looper.prepare() in Y thread, you're actually preparing looper in Y thread and therefore ready to call Looper.loop().

Create Handler in a class without get error "Looper not prepared"?

In my game, there is an game object class that need to use Handler to post a delay Runnable. However, everything I try to create an Handler in the object class, I receive error message:
Can't create handler inside thread
that has not called Looper.prepare()
I've Googled some solution, but all of them use another solution, not Handler. Is there any solution to use Handler in a normal class? Or any solution to run a Runnable after a determined delay?
I can't use sleep, because it paused all my game!
Thank you.
You are probably creating the Handler from a non-UI thread. Either (1) you attach your handler explicitly to the UI thread by passing the UI thread's looper to Handlers constructor, which means that messages posted to the Handler are also executed on the UI thread, or (2) you create a new Looper for the non-UI-thread: see here.
edit regarding (1): you would have to somehow pass the UI thread's looper to the "game object", for example when it is created. You can get a reference to UI's looper by calling getMainLooper() on a context (e.g. from an activity).
An alternative would be to create the handler in the activity and just pass the handler to your game object.

Categories

Resources