有人可以告诉我Thread和Handler之间的差异吗?当我们使用Thread并使用Handler时?
我的项目中有两个代码,但我无法理解它们。
final Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
// Do SomeThings
}
};
并且
private class readThread extends Thread
{
Handler mHandler;
readThread(Handler h){
mHandler = h;
this.setPriority(Thread.MIN_PRIORITY);
}
@Override
public void run()
{
// Do SomeThings
}
}
在另一种方法中,像这样调用处理程序
read_thread = new readThread(handler);
read_thread.start();
哪一个先跑?有人可以解释一下吗?
答案 0 :(得分:43)
相同:您可以异步执行任务而不会阻止当前代码,
差异:想象一下,你有Runnable r = new Runnable{...}
当您使用new Thread(r).start()
时,您实际上创建了一个新线程并异步运行任务。
当您使用new Handler().post(r)
(或Message
)时,您将Runnable
对象添加到Looper
并稍后在同一个帖子中执行代码。
Thread
,通常MainThread
或UIThread
包含Looper
。当MainThread
运行时,它将循环Looper
并逐个执行Runnable
。
首选线程时:
如果您正在进行网络通信或解码大型位图文件等繁重工作,则首选新线程。如果需要很多线程,可能会进一步优先ExecutorService
。
https://developer.android.com/reference/java/util/concurrent/ExecutorService.html
首选处理程序时:
如果要从其他线程更新UI对象(如TextView
文本),则必须只能在UI线程中更新UI对象。
此外,如果您只想稍后运行一些轻量代码(例如延迟300毫秒),您可以使用Handler
,因为它更轻,更快。
答案 1 :(得分:3)
线程是可以完成大部分工作的通用处理任务,但是他们不能做的一件事就是更新UI。
另一方面,处理程序是后台线程,允许您与UI线程通信(更新UI)。
例如,通过发布到处理程序的消息(Runnable)显示toast或更新进度条但是如果你将此runnable作为线程启动,则无法显示。
使用处理程序,您还可以使用MessageQueuing,schedule和repeat。
我还没遇到需要android的线程的情况。
我主要使用AsyncTasks和Handlers的组合。
上述任务的处理程序。
AsyncTasks用于下载/数据获取和轮询等。
答案 2 :(得分:2)
Thread
实际上创建了新线程 - 相对于当前线程在后台运行的作业的一部分。
Handler
本身不提供后台作业的任何机制 - 它只是访问与某个线程相关联的消息队列(Looper
)的工具。默认情况下,UI线程附加Looper
,因此通常的做法是使用Handler.post(Runable)
更新UI,这意味着在线程上执行与此Handler
相关联的一段代码。
只要Handler
提供Looper
,就无法在没有关联Looper
的帖子中创建它。
答案 3 :(得分:0)
简单地说
两者都是相同的概念,但有一些关键区别。 Thread是 java(java.lang)的概念,而Handler是 android(android.os)OS 的概念。如果使用Handler而不是Thread,则OS会自动管理后台进程的工作。但是,如果您使用的是Thread,则它不依赖于您的android OS。因此,与Handler相比,线程无法有效地管理内存。
答案 4 :(得分:0)
线程:
您可以将新线程用于长时间运行的后台任务,而不会影响UI线程。来自Java线程。但是在这里您不能从Thread更新UI。
由于普通Thread对于Android体系结构不是很有用,因此引入了用于线程的帮助程序类。 您可以在“线程性能文档”页面上找到查询的答案。
处理程序:
此类负责将任何任务放入消息队列并进行处理。每个处理程序都可以与一个线程和该线程的消息队列关联。
处理程序有两个主要用途:
Looper::Looper是使线程保持活动状态的工作程序,它循环遍历消息队列并将消息发送到相应的Handler。
消息队列:此类包含由循环程序分派的消息列表。您可以只调用Looper.myqueue()来获取消息列表。我们通常不会处理它。