Android 更新UI方法的深度解析
2016-11-03 14:22
411 查看
Android开发中,我们总是会遇到更新UI的场景。如果,我们直接在子线程中更新UI,那么会报错!提示我们,要在主线程中更新UI。那么具体更新UI有几种方法呢?下面就来列举这几种更新UI的方法。本篇是结合前面两篇文章有关Handler消息处理,如果你还没有了解,建议先看看这两篇文章,Android
源码解析Handler处理机制(一)和Android 源码解析Handler处理机制(二)。
1. Handler。
使用Handler更新UI,不再多说什么了,详情请看上文。
2.Handler的post()方法。
看看post()方法的源码,
getPostMessage()方法是将Runnable对象转化为消息对象Message的callback属性。而sendMessageDelayed()方法就不多说 了,又回到Handler的处理机制了,详情请看上文Android 源码解析Handler处理机制(二)。
PS:在上文中,我们提到过Handler的dispatchMessage()方法,
3. Activity的runOnUiThread()方法。
看看runOnUiThread()方法的源码,
4.View.post(Runnable r)方法。
该方法还是调用了Handler的post()方法。Handler的post()方法很重要哦!
(重要的事情说三遍!)有关Handler的post()方法的深度解析,详情请看,你不知道的Runnable接口,深度解析Runnable接口。
PS:还可以使用AsyncTask,来请求数据以及更新UI。此处就不多说,详情请看,Android 源码解析AsyncTask(一)和Android
源码解析AsyncTask(二)。
总结:
1.Activity的runOnUiThread()和 View.post(Runnable r)在本质上都是调用Handler的post()方法处理;
2.在子线程中直接更新UI,可以使用 Handler的post(),Activity的runOnUiThread()和 View.post(Runnable r)这三种方法。
推荐文章:Android 源码解析Handler处理机制(一)。
Android 源码解析Handler处理机制(二)。
你不知道的Runnable接口,深度解析Runnable接口。
源码解析Handler处理机制(一)和Android 源码解析Handler处理机制(二)。
1. Handler。
使用Handler更新UI,不再多说什么了,详情请看上文。
public class SecondActivity extends Activity { private static final int MSG_WHAT = 101; TextView tv; Button btn; private MyHadler mHandler1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); tv = (TextView) findViewById(R.id.tv); btn = (Button) findViewById(R.id.btn); mHandler1 = new MyHadler(); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { updateUi(); } }); } class MyHadler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case MSG_WHAT: String str = (String) msg.obj; tv.setText(str); } } } ; /** * */ private void updateUi1() { new Thread() { @Override public void run() { try { Thread.sleep(5 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } Message message = mHandler1.obtainMessage(); message.what = MSG_WHAT; message.obj = "来自子线程的数据"; mHandler1.sendMessage(message); } }.start(); } }
2.Handler的post()方法。
private void updateUi2() { new Thread() { @Override public void run() { try { Thread.sleep(5 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } mHandler1.post(new Runnable() { @Override public void run() { tv.setText(" Handler.post更新UI"); } }); } }.start(); }
看看post()方法的源码,
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }该方法调用了sendMessageDelayed(getPostMessage(r), 0)发送一条消息,下面首先看看getPostMessage()方法,
private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }
getPostMessage()方法是将Runnable对象转化为消息对象Message的callback属性。而sendMessageDelayed()方法就不多说 了,又回到Handler的处理机制了,详情请看上文Android 源码解析Handler处理机制(二)。
PS:在上文中,我们提到过Handler的dispatchMessage()方法,
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }可以看到,首先判断如果message的callback不等于null,则调用Handler的handleCallback()方法,否则调用Handler对象的handleMessage()方法。更加详细的描述,请看Android 源码解析Handler处理机制(二)。
3. Activity的runOnUiThread()方法。
/** * 通过runOnUiThread更新UI */ private void updateUi3(){ new Thread(){ @Override public void run() { try { Thread.sleep(3*1000); } catch (InterruptedException e) { e.printStackTrace(); } runOnUiThread(new Runnable() { @Override public void run() { tv.setText("runOnUiThread更新UI"); } }); } }.start(); }
看看runOnUiThread()方法的源码,
public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action); } else { action.run(); } }如果当前线程不是主线程,则调用Handler的post()方法;否则直接执行该方法。最重要的还是Handler的post()方法,相信不需要再多说什么了吧!
4.View.post(Runnable r)方法。
private void updateUi4(){ new Thread(){ @Override public void run() { super.run(); tv.post(new Runnable() { @Override public void run() { tv.setText("view post更新UI"); } }); } }.start(); }再来看看post()方法的源码,
public boolean post(Runnable action) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.post(action); } // Postpone the runnable until we know on which thread it needs to run. // Assume that the runnable will be successfully placed after attach. getRunQueue().post(action); return true; }
该方法还是调用了Handler的post()方法。Handler的post()方法很重要哦!
(重要的事情说三遍!)有关Handler的post()方法的深度解析,详情请看,你不知道的Runnable接口,深度解析Runnable接口。
PS:还可以使用AsyncTask,来请求数据以及更新UI。此处就不多说,详情请看,Android 源码解析AsyncTask(一)和Android
源码解析AsyncTask(二)。
总结:
1.Activity的runOnUiThread()和 View.post(Runnable r)在本质上都是调用Handler的post()方法处理;
2.在子线程中直接更新UI,可以使用 Handler的post(),Activity的runOnUiThread()和 View.post(Runnable r)这三种方法。
推荐文章:Android 源码解析Handler处理机制(一)。
Android 源码解析Handler处理机制(二)。
你不知道的Runnable接口,深度解析Runnable接口。
相关文章推荐
- Android 深度解析Activity启动流程与子线程更新UI
- Android线程模型解析(包括UI的更新)
- Android在子线程中更新Activity中UI的方法
- Android Service 通知Activity更新界面的方法研究|Service通过Broadcast更新UI
- Android UI框架深度解析
- Android:UI更新方法二:View.postInvalidate+Thread+Runnable
- Android线程模型解析(包括UI的更新)
- Android UI框架深度解析
- Android在子线程中更新Activity中UI的方法
- 子线程更新UI会发生android.view.ViewRoot$CalledFromWrongThreadException异常的解决方法
- Android:UI更新方法五:利用AsyncTask更新UI
- 子线程更新UI会发生android.view.ViewRoot$CalledFromWrongThreadException异常的解决方法 .
- Android Service 通知Activity更新界面的方法研究|Service通过Broadcast更新UI
- 【Android 非人为操作的UI更新】在onCreate()和onResume()等方法中的更新UI操作方法及获取View的相关消息
- Android线程模型解析(包括UI的更新)
- Android线程模型解析(包括UI的更新)
- Android线程模型解析(包括UI的更新)
- 利用Handler更新Android UI的另一种方法
- Android:UI更新方法三:Handler+Worker Thread
- Android:UI更新方法一:Handler+View.invalidate+Thread+Runnable