Android 为什么在 runOnUiThread 做同样的事情时使用处理程序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12618038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why to use Handlers while runOnUiThread does the same?
提问by Andro Selva
I have come across both Handlersand runOnUiThreadconcepts. But to me it still seems to be a doubt as on which facts do they differ exactly.
我遇到过处理程序和runOnUiThread概念。但对我来说,它们究竟在哪些事实上存在差异似乎仍然存在疑问。
They both are intended to do UI actions from a background thread. But what are the factors that are to be considered while we choose among the two methods.
它们都旨在从后台线程执行 UI 操作。但是,我们在这两种方法中进行选择时需要考虑哪些因素。
For example consider a Runnable
Thread
which performs a web service in the background and now I want to update the UI.
例如,考虑Runnable
Thread
在后台执行 Web 服务,现在我想更新 UI。
What would be the best way to update my UI? Should I go for Handler
or runOnUiThread
?
更新我的用户界面的最佳方式是什么?我应该去Handler
还是去runOnUiThread
?
I still know I could use a AsyncTask
and make use of onPostExecute
. But I just want to know the difference.
我仍然知道我可以使用 aAsyncTask
并使用onPostExecute
. 但我只想知道区别。
回答by HitOdessit
Activity.runOnUiThread()is a special case of more generic Handlers. With Handler
you can create your own event query within your own thread. Using Handlers
instantiated with the default constructordoesn'tmean "code will run on UI thread" in general. By default, handlers are bound to the Thread
from which they were instantiated from.
Activity.runOnUiThread()是更通用的Handlers 的一个特例。随着Handler
你可以创建自己的线程中自己的事件查询。通常,使用默认构造函数Handlers
实例化并不意味着“代码将在 UI 线程上运行”。默认情况下,处理程序绑定到它们被实例化的来源。Thread
To create a Handler
that is guaranteed to bind to the UI (main) thread, you should create a Handler
object bound to Main Looperlike this:
要创建一个Handler
保证绑定到 UI(主)线程的Handler
对象,您应该创建一个绑定到Main Looper的对象,如下所示:
Handler mHandler = new Handler(Looper.getMainLooper());
Moreover, if you check the implementation of the runOnUiThread()
method, it is using Handler
to do the things:
此外,如果您检查该runOnUiThread()
方法的实现,它正在Handler
用于执行以下操作:
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
As you can see from code snippet above, Runnable action
will be executed immediately if runOnUiThread()
is called from the UI thread. Otherwise, it will post it to the Handler
, which will be executed at some point later.
从上面的代码片段可以看出,Runnable action
如果runOnUiThread()
从 UI 线程调用,将立即执行。否则,它会将其发布到Handler
,稍后将执行该 。
回答by Vipin Sahu
Handler have many work like message passingand frequent UI update if you start A Thread for any running a task .A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue ,, which is very useful in many application like bluetooth chat ,, wifi chat ... and handler has as Method PostDelay and PostAtTime by which you can play around any view to animate and change visibility and so on
如果您为任何正在运行的任务启动一个线程,处理程序有许多工作,例如消息传递和频繁的 UI 更新。处理程序允许您发送和处理与线程的 MessageQueue 关联的 Message 和 Runnable 对象,这在许多应用程序(如蓝牙)中非常有用chat ,, wifi chat ... 和 handler 有方法 PostDelay 和 PostAtTime,通过它你可以播放任何视图来设置动画和改变可见性等等
You must look in this
你必须看看这个
http://developer.android.com/guide/components/processes-and-threads.html
http://developer.android.com/guide/components/processes-and-threads.html
http://developer.android.com/tools/testing/activity_testing.html
http://developer.android.com/tools/testing/activity_testing.html
回答by Vipin Sahu
Following HitOdessit's answer.
按照 HitOdessit 的回答。
You can create a class like this.
您可以创建这样的类。
public class Global{
private static Handler mHandler = new Handler(Looper.getMainLooper());
public static void runOnUiThread(Runnable action){
mHandler.post(action);
}
}
And then call it like this.
然后这样称呼它。
Global.runOnUiThread(new Runnable(){
//Your code
});
And this can be run from anywhere (where you have access to your Global class).
这可以从任何地方运行(您可以访问 Global 类)。
回答by Ravindra babu
What would be the best way to update my UI? Should I go for Handler or runOnUiThread?
更新我的用户界面的最佳方式是什么?我应该选择 Handler 还是 runOnUiThread?
If your Runnable
needs to update UI, post it on runOnUiThread
.
如果您Runnable
需要更新 UI,请将其发布到runOnUiThread
.
But it's not always possible to post Runnable
on UI Thread.
但是并不总是可以Runnable
在 UI Thread 上发帖。
Think of scenario, where you want need to execute Network/IO operationOr invoke a web service. In this case, you can't post Runnable
to UI Thread. It will throw android.os.NetworkOnMainThreadException
想一想您需要执行网络/IO 操作或调用Web 服务的场景。在这种情况下,您不能发布Runnable
到 UI 线程。它会抛出android.os.NetworkOnMainThreadException
These type of Runnable
should run on different thread like HandlerThread. After completing your operation, you can post result back to UI Thread by using Handler
, which has been associated with UI Thread.
这些类型Runnable
应该在不同的线程上运行,比如HandlerThread。完成操作后,您可以使用Handler
已与 UI 线程关联的将结果发布回UI 线程。
public void onClick(View view) {
// onClick on some UI control, perform Network or IO operation
/* Create HandlerThread to run Network or IO operations */
HandlerThread handlerThread = new HandlerThread("NetworkOperation");
handlerThread.start();
/* Create a Handler for HandlerThread to post Runnable object */
Handler requestHandler = new Handler(handlerThread.getLooper());
/* Create one Handler on UI Thread to process message posted by different thread */
final Handler responseHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
//txtView.setText((String) msg.obj);
Toast.makeText(MainActivity.this,
"Runnable on HandlerThread is completed and got result:"+(String)msg.obj,
Toast.LENGTH_LONG)
.show();
}
};
NetworkRunnable r1 = new NetworkRunnable("http://www.google.com/",responseHandler);
NetworkRunnable r2 = new NetworkRunnable("http://in.rediff.com/",responseHandler);
requestHandler.post(r1);
requestHandler.post(r2);
}
class NetworkRunnable implements Runnable{
String url;
Handler uiHandler;
public NetworkRunnable(String url,Handler uiHandler){
this.url = url;
this.uiHandler=uiHandler;
}
public void run(){
try {
Log.d("Runnable", "Before IO call");
URL page = new URL(url);
StringBuffer text = new StringBuffer();
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
BufferedReader buff = new BufferedReader(in);
String line;
while ((line = buff.readLine()) != null) {
text.append(line + "\n");
}
Log.d("Runnable", "After IO call:"+ text.toString());
Message msg = new Message();
msg.obj = text.toString();
/* Send result back to UI Thread Handler */
uiHandler.sendMessage(msg);
} catch (Exception err) {
err.printStackTrace();
}
}
}
回答by Animesh
Handlers were the old way (API Level 1) of doing stuff, and then AsycTask
(API Level 3) were introduced, along with a stronger focus on using runOnUIThread
(API Level 1). You should avoid using handlers as much as possible, and prefer the other two depending on your need.
处理程序是旧的做事方式(API 级别 1),然后AsycTask
(API 级别 3)被引入,同时更加注重使用runOnUIThread
(API 级别 1)。您应该尽可能避免使用处理程序,并根据需要选择其他两个。