为什么要使用处理程序而runOnUiThread也一样?

我遇到了Handler和runOnUiThread两个概念。 但对我来说,它似乎仍然是一个疑问,因为它们究竟在哪些事实上有所不同。

他们都打算从后台线程做UI操作。 但是我们select这两种方法时要考虑哪些因素呢?

例如,考虑一个在后台执行Web服务的可运行Thread ,现在我想更新UI。

什么是最好的方式来更新我的用户界面? 我应该去HandlerrunOnUiThread

我仍然知道我可以使用AsyncTask并使用onPostExecute 。 但我只想知道其中的差别。

Activity.runOnUiThread()是更一般处理程序的特例。 使用Handler您可以在自己的线程中创build自己的事件查询。 使用默认构造函数实例化的Handlers 并不意味着“ 代码将在UI线程上运行 ”。 默认情况下,处理程序绑定到从中实例化的Thread

要创build保证绑定到UI(主)线程的Handler你应该像下面这样创build绑定到Main Looper的 Handler对象:

 Handler mHandler = new Handler(Looper.getMainLooper()); 

而且,如果您检查runOnuiThread()方法的实现,则使用Handler来执行以下操作:

  public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action); } else { action.run(); } } 

从上面的代码片断可以看到,如果从UI线程调用runOnUiThread() ,则可立即执行Runnable action 。 否则,它会将其发布到Handler ,稍后将在稍后执行。

处理程序有许多工作,如消息传递和频繁的UI更新,如果你启动一个线程的任何运行任务。处理程序允许您发送和处理与线程的MessageQueue相关的消息和Runnable对象,这是很多应用程序,如蓝牙聊天,无线聊天…和处理程序具有方法PostDelay和PostAtTime,您可以在任何视图中播放animation和更改可见性等

你必须看看这个

http://developer.android.com/guide/components/processes-and-threads.html

http://developer.android.com/tools/testing/activity_testing.html

HitOdessit的答案。

你可以像这样创build一个类。

 public class Global{ private static Handler mHandler = new Handler(Looper.getMainLooper()); public static void runOnUiThread(Runnable action){ mHandler.post(action); } } 

然后像这样称呼它。

 Global.runOnUiThread(new Runnable(){ //Your code }); 

这可以从任何地方(你有权访问你的全球课程)运行。

处理程序是旧的方法(API级别1)做的东西,然后AsycTask (API级别3),同时更强调使用runOnUIThread (API级别1)。 你应该尽可能地避免使用处理程序,并根据你的需要select其他两个。

什么是最好的方式来更新我的用户界面? 我应该去处理程序或runOnUiThread?

如果您的Runnable需要更新UI,请将其发布到runOnUiThread

但是在UI线程上发布Runnable并不总是可能的。

想想你想要执行networking/ IO操作的场景,或者调用Web服务。 在这种情况下,您不能将Runnable发布到UI线程。 它会抛出android.os.NetworkOnMainThreadException

这些types的Runnable应该像HandlerThread一样运行在不同的线程上。 完成操作后,可以使用与UI线程关联的Handler将结果发回到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(); } } }