buder

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的方法中进行的界面更新。

 

 

posted on 2017-09-25 09:58  buder  阅读(203)  评论(0编辑  收藏  举报

导航