I am new to Android. I want to know what the Looper
class does and also how to use it. I have read the Android Looper class documentation but I am unable to completely understand it.
I have seen it in a lot of places but unable to understand its purpose. Can anyone help me by defining the purpose of Looper
and also by giving a simple example if possible?
相关问题
- How can I create this custom Bottom Navigation on
- Bottom Navigation View gets Shrink Down
- How to make that the snackbar action button be sho
- Listening to outgoing sms not working android
- How to create Circular view on android wear?
相关文章
- android开发 怎么把图片放入drawable的文件夹下
- android上如何获取/storage/emulated/下的文件列表
- androidStudio有个箭头不认识
- SQLite不能创建表
- Windows - Android SDK manager not listing any plat
- Animate Recycler View grid when number of columns
- Why is the app closing suddenly without showing an
- Android OverlayItem.setMarker(): Change the marker
This answer has nothing to do with the question, but the use of looper and the way people created the handler and looper in ALL the answers here are plain bad practice (some explanations are correct though), I have to post this:
and for a full implementation
Handling multiple down or upload items in a Service is a better example.
Handler
andAsnycTask
are often used to propagate Events/Messages between the UI (thread) and a worker thread or to delay actions. So they are more related to UI.A
Looper
handles tasks (Runnables, Futures) in a thread related queue in the background - even with no user interaction or a displayed UI (app downloads a file in the background during a call).You can better understand what Looper is in the context of GUI framework. Looper is made to do 2 things.
1) Looper transforms a normal thread, which terminates when its run() method return, into something run continuously until Android app is running, which is needed in GUI framework (Technically, it still terminates when run() method return. But let me clarify what I mean in below).
2) Looper provides a queue where jobs to be done are enqueued, which is also needed in GUI framework.
As you may know, when an application is launched, the system creates a thread of execution for the application, called “main”, and Android applications normally run entirely on a single thread by default the “main thread”. But main thread is not some secret, special thread. It's just a normal thread similar to threads you create with
new Thread()
code, which means it terminates when its run() method return! Think of below example.Now, let's apply this simple principle to Android apps. What would happen if an Android app runs on normal thread? A thread called "main" or "UI" or whatever starts your application, and draws all UI. So, the first screen is displayed to users. So what now? The main thread terminates? No, it shouldn’t. It should wait until users do something, right? But how can we achieve this behavior? Well, we can try with
Object.wait()
orThread.sleep()
. For example, main thread finishes its initial job to display first screen, and sleeps. It awakes, which means interrupted, when a new job to do is fetched. So far so good, but at this moment we need a queue-like data structure to hold multiple jobs. Think about a case when a user touches screen serially, and a task takes longer time to finish. So, we need to have a data structure to hold jobs to be done in first-in-first-out manner. Also, you may imagine, implementing ever-running-and-process-job-when-arrived thread using interrupt is not easy, and leads to complex and often unmaintainable code. We'd rather create a new mechanism for such purpose, and that is what Looper is all about. The official document of Looper class says, "Threads by default do not have a message loop associated with them", and Looper is a class "used to run a message loop for a thread". Now you can understand what it means.To make things more clear, let's check the code where main thread is transformed. It all happens in ActivityThread class. In its main() method, you can find below code, which turns a normal main thread into something what we need.
and
Looper.loop()
method loop infinitely and dequeue a message and process one at a time:So, basically Looper is a class that is made to address a problem that occurs in GUI framework. But this kind of needs can also happen in other situation as well. Actually it is a pretty famous pattern for multi threads application, and you can learn more about it in "Concurrent Programming in Java" by Doug Lea(Especially, chapter 4.1.4 "Worker Threads" would be helpful). Also, you can imagine this kind of mechanism is not unique in Android framework, but all GUI framework may need somewhat similar to this. You can find almost same mechanism in Java Swing framework.
Android
Looper
is a wrapper to attachMessageQueue
toThread
and it manages Queue processing. It looks very cryptic in Android documentation and many times we may faceLooper
related UI access issues. If we don't understand the basics it becomes very tough to handle.Here is an article which explains
Looper
life cycle, how to use it and usage ofLooper
inHandler
Looper = Thread + MessageQueue
Life span of java Thread is over after completion of
run()
method. Same thread can't be started again.Looper transforms normal
Thread
into a message loop. Key methods ofLooper
are :This mindorks article by Janishar explains the core concepts in nice way.
Looper
is associated with a Thread. If you needLooper
on UI thread,Looper.getMainLooper()
will return associated thread.You need
Looper
to be associated with a Handler.Looper
,Handler
, andHandlerThread
are the Android’s way of solving the problems of asynchronous programming.Once you have
Handler
, you can call below APIs.HandlerThread is handy class for starting a new thread that has a looper. The looper can then be used to create handler classes
In some scenarios, you can't run
Runnable
tasks on UI Thread. e.g. Network operations : Send message on a socket, open an URL and get content by readingInputStream
In these cases,
HandlerThread
is useful. You can getLooper
object fromHandlerThread
and create aHandler
onHandlerThread
instead of main thread.The HandlerThread code will be like this:
Refer to below post for example code:
Android: Toast in a thread
Understanding Looper Threads
A java Thread a unit of execution which was designed to perform a task in its run() method & terminate after that:
But in Android there are many use cases where we need to keep a Thread alive and wait for user inputs/events for eg. UI thread aka
Main Thread
.Main thread in Android is a Java thread which is first started by JVM at the launch of an app and keeps on running till the user choose to close it or encounters unhandled exception.
Now point to note here is although main thread is Java thread yet it keeps on listening to user events and draw 60 fps frames on screen and still it wont die after each cycle. how is it so?
Threads by default do not have a message loop associated with them but you can assign one by calling Looper.prepare() in the run method and then call the Looper.loop().
If you want to dig deeper how Looper manage
Message
object queue then you can have a look at source code ofLooperclass
:Below is an example of how you can create a
Looper Thread
and communicate withActivity
class usingLocalBroadcast
Usage:
Can we use Async task or Intent Services instead?
Async tasks are designed to perform a short operation in background and give progres & results on UI thread. Async tasks have limits like you cant create more than 128 Async tasks and
ThreadPoolExecutor
will allow only upto 5 Async tasks.IntentServices
are also designed to do background task for a little longer duration and you can useLocalBroadcast
to communicate withActivity
. But services get destroyed after task execution. If you want to keep it running for a long time than you need to do hecks likewhile(true){...}
.Other meaningful use cases for Looper Thread:
Used for 2 way socket communication where server keep on listening to Client socket and write back acknowledgment
Bitmap processing in background. Pass the image url to Looper thread and it will apply filter effects and store it in tempe rory location and then broadcast temp path of image.