我是安卓系统的新手。我想知道Looper类做什么,以及如何使用它。我已经阅读了Android Looper类文档,但我无法完全理解它。 我在很多地方见过它,但无法理解它的目的。谁能帮我定义一下Looper的目的,如果可能的话,也给我一个简单的例子?
当前回答
什么是环形使者?
从文档
电影
循环程序类,用于为线程运行消息循环。默认情况下,线程没有与之关联的消息循环;要创建一个循环,在要运行循环的线程中调用prepare(),然后调用loop()让它处理消息,直到循环停止。
A Looper is a message handling loop: An important character of Looper is that it's associated with the thread within which the Looper is created The Looper class maintains a MessageQueue, which contains a list messages. An important character of Looper is that it's associated with the thread within which the Looper is created. The Looper is named so because it implements the loop – takes the next task, executes it, then takes the next one and so on. The Handler is called a handler because someone could not invent a better name Android Looper is a Java class within the Android user interface that together with the Handler class to process UI events such as button clicks, screen redraws and orientation switches.
它是如何工作的?
创造电影
线程通过在运行后调用loop .prepare()来获得Looper和MessageQueue。loop .prepare()标识调用线程,创建一个Looper和MessageQueue对象并关联线程
示例代码
class MyLooperThread extends Thread {
public Handler mHandler;
public void run() {
// preparing a looper on current thread
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
// this will run in non-ui/background thread
}
};
Looper.loop();
}
}
欲了解更多信息,请查看下面的帖子
在Android中,Looper, Handler和MessageQueue之间是什么关系? Android内脏:环形器和处理程序的介绍 理解Android核心:Looper, Handler和HandlerThread Android中的Handler 什么是Android Looper? Android: Looper, Handler, HandlerThread。我一部分。 Android中的MessageQueue和Looper
其他回答
I will try to explain the purpose of looper class as simple as possible. With a normal thread of Java when the run method completes the execution we say the thread has done it's job and thread lives no longer after that. what if we want to execute more tasks throughout our program with that same thread which is not living anymore? Oh there is a problem now right? Yes because we want to execute more tasks but the thread in not alive anymore. It is where the Looper comes in to rescue us. Looper as the name suggests loops. Looper is nothing more than an infinite loop inside your thread. So, it keeps the thread alive for an infinite time until we explicitly calls quit() method. Calling quit() method on the infinitely alive thread will make the condition false in the infinite loop inside the thread thus, infinite loop will exit. so, the thread will die or will no longer be alive. And it's critical to call the quit() method on our Thread to which looper is attached otherwise they will be there in your system just like Zombies. So, for example if we want to create a background thread to do some multiple tasks over it. we will create a simple Java's thread and will use Looper class to prepare a looper and attach the prepared looper with that thread so that our thread can live as longer as we want them because we can always call quit() anytime whenever we want to terminate our thread. So our the looper will keep our thread alive thus we will be able to execute multiple tasks with the same thread and when we are done we will call quit() to terminate the thread. What if we want our Main thread or UI thread to display the results computed by the background thread or non-UI thread on some UI elements? for that purpose there comes in the concept of Handlers; via handlers we can do inter-process communication or say via handlers two threads can communicate with each other. So, the main thread will have an associated Handler and Background thread will communicate with Main Thread via that handler to get the task done of displaying the results computed by it on some UI elements on Main thread. I know I am explaining only theory here but try to understand the concept because understanding the concept in depth is very important. And I am posting a link below which will take you to a small video series about Looper, Handler and HandlerThread and I will highly recommend watching it and all these concepts will get cleared with examples there.
https://www.youtube.com/watch?v=rfLMwbOKLRk&list=PL6nth5sRD25hVezlyqlBO9dafKMc5fAU2&index=1
Looper允许在单个线程上按顺序执行任务。handler定义了我们需要执行的任务。这是我在这个例子中试图说明的一个典型场景:
class SampleLooper extends Thread {
@Override
public void run() {
try {
// preparing a looper on current thread
// the current thread is being detected implicitly
Looper.prepare();
// now, the handler will automatically bind to the
// Looper that is attached to the current thread
// You don't need to specify the Looper explicitly
handler = new Handler();
// After the following line the thread will start
// running the message loop and will not normally
// exit the loop unless a problem happens or you
// quit() the looper (see below)
Looper.loop();
} catch (Throwable t) {
Log.e(TAG, "halted due to an error", t);
}
}
}
现在我们可以在一些其他线程(比如ui线程)中使用处理程序将任务发布到Looper上执行。
handler.post(new Runnable()
{
public void run() {
//This will be executed on thread using Looper.
}
});
在UI线程上,我们有一个隐式的循环器,允许我们处理UI线程上的消息。
您可以在GUI框架的上下文中更好地理解什么是Looper。《环形使者》有两项任务。
Looper将一个正常的线程转换为持续运行的线程,直到Android应用程序运行为止。 Looper提供了一个队列,要完成的作业将在其中排队。
正如你所知道的,当一个应用程序启动时,系统为应用程序创建了一个执行线程,称为“主线程”,而Android应用程序通常完全运行在一个线程上,默认情况下是“主线程”。但是主线程并不是一个秘密的、特殊的主线程。它只是一个普通的线程,类似于你可以用new thread()创建的线程,这意味着它在run()方法返回时终止!想想下面的例子。
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
Now, let's apply this simple principle to Android apps. What would happen if an Android app runs on a 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. 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() or Thread.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.
为了使事情更清楚,让我们检查转换主线程的代码。这一切都发生在ActivityThread类中。在它的main()方法中,您可以找到下面的代码,它将普通线程转换为我们需要的线程。
public final class ActivityThread {
...
public static void main(String[] args) {
...
Looper.prepareMainLooper();
Looper.loop();
...
}
}
和loop .loop()方法无限循环,每次出队列并处理一个消息:
public static void loop() {
...
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
...
msg.target.dispatchMessage(msg);
...
}
}
So, basically, Looper is a class that is made to address a problem that occurs in the GUI framework. But this kind of need can also happen in other situations as well. Actually, it is a pretty famous pattern for multi-thread applications, 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. You can find almost same mechanism in Java Swing framework too.
这个答案与问题无关,但looper的使用以及人们在这里的所有答案中创建处理程序和looper的方式都是明显的坏习惯(尽管有些解释是正确的),我不得不发布这个:
HandlerThread thread = new HandlerThread(threadName);
thread.start();
Looper looper = thread.getLooper();
Handler myHandler = new Handler(looper);
以及一个完整的实现
Android Looper是一个包装器,用于将messagqueuue附加到线程,并管理队列处理。它在Android文档中看起来非常神秘,很多时候我们可能会面临与Looper相关的UI访问问题。如果我们不了解基础知识,就很难处理。
这是一篇文章,解释了Looper的生命周期,如何使用它,以及在Handler中使用Looper
循环器=线程+消息队列
推荐文章
- 改变开关的“开”色
- 以编程方式将EditText的输入类型从PASSWORD更改为NORMAL,反之亦然
- 如何在隐藏和查看密码之间切换
- 在Android上调整一个大的位图文件到缩放输出文件
- 如何更改Android版本和代码版本号?
- Android Studio突然无法解析符号
- 应用程序重新启动而不是恢复
- 跨线程操作无效:控件“textBox1”从创建它的线程以外的线程访问
- 如何设置整个应用程序在纵向模式?
- Android中文本的阴影效果?
- 以编程方式设置TextView的布局权重
- Android -如何覆盖“后退”按钮,所以它不完成()我的活动?
- 如何从通知点击发送参数到一个活动?
- 导航目标xxx对于这个NavController是未知的
- 使用ConstraintLayout均匀间距的视图