201709025工作日记--更新UI方法
1.handler+Thread 和 runOnUIThread 和 handler.post 方法
区别:
从实现原理上,两者别无二致,runOnUiThread
也是借助Handler
实现的。
对于使用场景,runOnUiThread
用法简单,并且共享了同一个Handler
,用起来高效、方便。另外,如果在主线程中直接调用,runOnUiThread
也可以判断并立即执行,不再推入消息队列。
而Handler
由于更加基础,所以可定制性要比runOnUiThread
强,可以实现标记、延时等功能,并且可以推入其他消息循环线程而非主线程。
handler + Thread 处理
需要在主线程中创建一个handler和一个线程,通过重写handler的handleMessage()方法更新UI界面。例子:
public class MainActivity extends Activity { private EditText UITxt; private Button updateUIBtn; private UIHandler UIhandler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); UITxt = (EditText)findViewById(R.id.ui_txt); updateUIBtn = (Button)findViewById(R.id.update_ui_btn); updateUIBtn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub UIhandler = new UIHandler(); UIThread thread = new UIThread(); thread.start(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } private class UIHandler extends Handler{ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); Bundle bundle = msg.getData(); String color = bundle.getString("color"); UITxt.setText(color); } } private class UIThread extends Thread{ @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Message msg = new Message(); Bundle bundle = new Bundle(); bundle.putString("color", "黄色"); msg.setData(bundle); MainActivity.this.UIhandler.sendMessage(msg); } } }
Activity.runOnUiThread(Runnable)处理
利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThread(Runnable)。
Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程。
public class TestActivity extends Activity { Button btn; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.handler_msg); btn = (Button) findViewById(R.id.button1); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { // TODO Auto-generated method stub new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub // 模拟耗时的操作。 try { Thread.sleep(10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 更新主线程UI TestActivity.this.runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub btn.setText("更新完毕!"); } }); } }).start(); } }); }
runOnUiThread是直接将一个Runnable对象封装成Message,交给主线程的Looper去执行。执行代码就是:
handler.post(mRunnable);
而Handler想要得到同样的效果,那首先Handler绑定的Looper必须是主线程的Looper,可以通过Looper.getMainLooper()获取。然后也是通过post去发送一个runable对象。
本质是没有任何差别的。
handler.post()处理
private Handler mHandler;//全局变量 @Override protected void onCreate(Bundle savedInstanceState) { mHandler = new Handler(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000);//在子线程有一段耗时操作,比如请求网络 mHandler.post(new Runnable() { //和Activity.runOnUiThread()相比完全一样, @Override //一个是activity的方法,一个是handler的方法 public void run() { mTestTV.setText("This is post");//更新UI } }); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); }
总结:
Handler+Thread与handler.post()都是在主线程中创建一个Handler,通过子线程的message进行通信交互,都是在handler为媒介进行处理。而Activity.runOnUiThread()是activity的方法中进行的界面更新。
啊
啊