1. activity runonuiThread
    首先判断当前线程是不是UI线程,如果不是UI线程,activity自己有一个handler,通过handler的post 方法来发送一个runnable。如果是UI线程就调用UI 线程的run方法,其实内部还是通过handler机制更新UI
  2. handler post(runnable)
    内部调用sendMessageDelayed()方法 和sendMessage本质上是相同的
  3. handler sendMessage(最常见)
  4. view post
    首先判断AttachInfo是否为空,如果不等于空,则通过AttachInfo拿到handler 。通过AttachInfo.handler.post(runnable)方法来更新UI 。不为空的情况下通过ViewRootImpl.getRunQueue().post(runnable);来更新UI
    总结:这四种方法,本质上还是通过handler机制来更新UI 。只是在内部有些代码上的差异
    代码如下
public class UpdateUIActivity extends Activity {    private TextView text;    private Handler handler = new Handler() {        public void handleMessage(android.os.Message msg) {            text.setText("handler2sendEmptyMessage UI");       };    };    private void handler1() {        // 第一中方式        handler.post(new Runnable() {            @Override            public void run() {                // TODO Auto-generated method stub                text.setText("handelr UI");            }        });    }    private void handler2() {        // 第2中方式        handler.sendEmptyMessage(1);    }    private  void updateUI(){        // 第3中方式        runOnUiThread(new Runnable() {            @Override            public void run() {                // TODO Auto-generated method stub                text.setText("runOnUiThread UI");            }        });    }    private void viewUI(){        // 第4中方式        text.post(new Runnable() {            @Override            public void run() {                // TODO Auto-generated method stub                text.setText("viewUIpost UI");            }        });    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_update_ui);        text = (TextView) findViewById(R.id.textview1);        new Thread() {            @Override            public void run() {                             try {                    Thread.sleep(2000);                    //handler2();                    //updateUI();                    //viewUI();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }.start();    }}

非UI线程真的不能更新UI么?
在有些情况下非UI 线程是可以更新UI 的。
可以更新的情况

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_update_ui);        text = (TextView) findViewById(R.id.textview1);        new Thread() {            @Override            public void run() {                     text.setText(" UI");            }        }.start();    }

报错的情况

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_update_ui);        text = (TextView) findViewById(R.id.textview1);        new Thread() {            @Override            public void run() {                             try {                    Thread.sleep(2000);                    text.setText(" UI");                    //handler2();                    //updateUI();                    //viewUI();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }.start();    }

所有更新UI 的操作都会调用view的 invalidate()方法,当我们调用textview.setText()方法会调用checkForRelayout()方法,重新绘制界面,其内部也会调用invalidate()方法。invalidate()方法内部调用ViewParent的invalidateChild()方法,其实真正判断当前线程是否在UI线程中更新界面的操作就是在ViewParent类当中,ViewParent是ViewRootImpl的一个实现类。对于上面的情况,当线程不休眠的时候ViewRootImpl还没有被创建出来,ViewRootImpl在activity的onResume()方法中被创建,onCreate()方法在onResume()方法之前,所以线程不休眠时就没有创建ViewRootImpl,所以就判断是在UI线程更新UI 就可以更新成功。
Avctivity 的启动类是activityThread

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. button
  3. Android(安卓)DialogFragment底部弹出菜单
  4. Android(安卓)Loader详解二:使用加载器
  5. Android中service的使用
  6. Android中Activity,View,Window之间的关系
  7. view中显示部分区域
  8. adb 5037 端口占用解决
  9. Android(安卓)2.3 CTS测试修改测试结果和调试方法

随机推荐

  1. 寻找android中的设计模式(三)
  2. Android绘制进阶之四:在位图上绘制文本并
  3. android与其他应用的交互
  4. No resource found that matches the giv
  5. android AlertDialog布局 ——2
  6. 【Android(安卓)开发教程】LinearLayout
  7. adb:) adb install
  8. 使用ViewPager来实现Tab的效果
  9. Android(安卓)studio中为app添加多语言支
  10. Android(安卓)Studio无法启动,gradle下载