我是安卓系统的新手。我想知道Looper类做什么,以及如何使用它。我已经阅读了Android Looper类文档,但我无法完全理解它。 我在很多地方见过它,但无法理解它的目的。谁能帮我定义一下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
其他回答
java线程的生命周期在run()方法完成后结束。同一线程不能再次启动。
Looper将普通线程转换为消息循环。Looper的主要方法有:
void prepare ()
将当前线程初始化为循环程序。这使您有机会创建处理程序,然后在实际开始循环之前引用此循环程序。请确保在调用此方法后调用loop(),并通过调用quit()结束它。
void loop ()
在此线程中运行消息队列。确保调用quit()来结束循环。
void quit()
退出循环器。 导致loop()方法终止,而不处理消息队列中的任何其他消息。
Janishar的这篇mindorks文章很好地解释了核心概念。
循环程序与线程相关联。如果你在UI线程上需要Looper, loop . getmainlooper()将返回相关的线程。
您需要将Looper与Handler相关联。
Looper, Handler和HandlerThread是Android解决异步编程问题的方法。
有了Handler之后,就可以调用下面的api了。
post (Runnable r)
导致Runnable r被添加到消息队列。可运行对象将在附加此处理程序的线程上运行。
boolean sendMessage (Message msg)
在当前时间之前的所有挂起消息之后,将消息压入消息队列的末尾。它将在附加到此处理程序的线程中的handleMessage(Message)中接收。
HandlerThread是一个方便的类,用于启动具有循环程序的新线程。循环程序可以用来创建处理程序类
在某些情况下,你不能在UI线程上运行可运行任务。 例如,网络操作:在套接字上发送消息,打开URL并通过读取InputStream获取内容
在这些情况下,HandlerThread很有用。你可以从HandlerThread获取Looper对象,并在HandlerThread上创建Handler而不是主线程。
HandlerThread代码是这样的:
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
参考下面的示例代码:
Android:在线程中吐司
循环器有一个同步的messagqueuue,用于处理放置在队列上的消息。
它实现了线程特定的存储模式。
每个线程只有一个Looper。关键方法包括prepare()、loop()和quit()。
prepare()将当前线程初始化为循环程序。prepare()是使用ThreadLocal类的静态方法,如下所示。
public static void prepare(){
...
sThreadLocal.set
(new Looper());
}
在运行事件循环之前,必须显式地调用Prepare()。 loop()运行事件循环,等待消息到达特定线程的消息队列。一旦接收到下一个Message, loop()方法将该Message分派给它的目标处理程序 Quit()关闭事件循环。它不会终止循环,而是将一条特殊消息编入队列
Looper可以通过几个步骤在线程中编程
扩展的线程 调用loop .prepare()将Thread初始化为Looper 创建一个或多个Handler来处理传入消息 调用loop .loop()来处理消息,直到循环被告知quit()。
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线程上的消息。
Android Looper是一个包装器,用于将messagqueuue附加到线程,并管理队列处理。它在Android文档中看起来非常神秘,很多时候我们可能会面临与Looper相关的UI访问问题。如果我们不了解基础知识,就很难处理。
这是一篇文章,解释了Looper的生命周期,如何使用它,以及在Handler中使用Looper
循环器=线程+消息队列
在Service中处理多个下拉或上传项是一个更好的例子。
Handler和AsnycTask通常用于在UI(线程)和工作线程之间传播事件/消息或延迟操作。所以它们与UI更相关。
循环程序在后台处理线程相关队列中的任务(Runnables, Futures) -即使没有用户交互或显示UI(应用程序在调用期间在后台下载文件)。
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- 自动化invokerrequired代码模式
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?