美文网首页
Android子线程更新ui的几种方式

Android子线程更新ui的几种方式

作者: 7i昂 | 来源:发表于2019-08-15 16:46 被阅读0次

    为什么子线程中不能更新ui

    Android实现View更新有两组方法,分别是invalidate和postInvalidate。前者在UI线程中使用,后者在非UI线程即子线程中使用。换句话说,在子线程调用 invalidate 方法会导致线程不安全。熟悉View工作原理的人都知道,invalidate 方法会通知 view 立即重绘,刷新界面。作一个假设,现在我用 invalidate 在子线程中刷新界面,同时UI线程也在用 invalidate 刷新界面,这样会不会导致界面的刷新不能同步?这就是invalidate不能在子线程中使用的原因。

    public class MainActivity extends AppCompatActivity { private TextView main_tv;
    
        @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            main_tv = (TextView) findViewById(R.id.main_tv); new Thread(new Runnable() {
    
                @Override public void run() {
                    main_tv.setText("子线程中访问");
                }
            }).start();
    
        }
    
    }
    

    程序正常运行不报错

    
    public class MainActivity extends AppCompatActivity {
    
        private TextView main_tv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            main_tv = (TextView) findViewById(R.id.main_tv);
    
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    main_tv.setText("子线程中访问");
                }
            }).start();
    
        }
    
    }
    
    @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_test1:
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            mTvTest.setText("子线程真的可以更新UI吗?");
                        }
                    }).start();
                    break;
              }
        }
    

    以上两种都报错

    正确更新的方式有

    private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 100) {
                    mTvTest.setText("由Handler发送消息");
                }
            }
     };
    
    
    @Override
        public void onClick(View v) {
            switch (v.getId()) {
                
                case R.id.btn_test2:   //通过发送消息
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            mHandler.sendEmptyMessage(100);
                        }
                    }).start();
                    break;
                case R.id.btn_test3:  //通过Handler.post方法
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            mHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    mTvTest.setText("handler.post");
                                }
                            });
                        }
                    }).start();
                    break;
                case R.id.btn_test4:  //通过 view.post方法
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            mTvTest.post(new Runnable() {
                                @Override
                                public void run() {
                                    mTvTest.setText("view.post");
                                }
                            });
                        }
                    }).start();
                    break;
                case R.id.btn_test5:  //通过 activity 的 runOnUiThread方法
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mTvTest.setText("runOnUIThread");
                                }
                            });
                        }
                    }).start();
                    break;
                default:
                    break;
            }
        }
    

    相关文章

      网友评论

          本文标题:Android子线程更新ui的几种方式

          本文链接:https://www.haomeiwen.com/subject/uyozjctx.html