为什么要使用处理程序而runOnUiThread也一样?
我遇到了Handler和runOnUiThread两个概念。 但对我来说,它似乎仍然是一个疑问,因为它们究竟在哪些事实上有所不同。
他们都打算从后台线程做UI操作。 但是我们select这两种方法时要考虑哪些因素呢?
例如,考虑一个在后台执行Web服务的可运行Thread
,现在我想更新UI。
什么是最好的方式来更新我的用户界面? 我应该去Handler
或runOnUiThread
?
我仍然知道我可以使用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(); } } }