当前位置:   article > 正文

AndroidStudio子线程更新UI的几种方式_子线程更新ui可以catch吗

子线程更新ui可以catch吗

在安卓开发中,大部分情况下是不能在子线程直接更新UI的,只能在UI线程更新UI,其根本原因在于加入在一个Activity中有多个线程去更新UI,且没有加锁机制,可能会产生界面混乱的情况,但是如果都加锁的话会导致性能下降。所以android提供了一套子线程更新UI的机制。在某些特殊的情况下是可以直接在子线程更新UI的。

布局界面只有一个textView

  1. import android.annotation.SuppressLint;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.os.Handler;
  5. import android.os.Message;
  6. import android.support.annotation.Nullable;
  7. import android.widget.TextView;
  8. public class HandlerActivity extends Activity {
  9. private TextView textView;
  10. @SuppressLint("HandlerLeak")
  11. Handler handler = new Handler() {
  12. @Override
  13. public void handleMessage(Message msg) {
  14. textView.setText("okok");
  15. super.handleMessage(msg);
  16. }
  17. };
  18. //第一种 handler post runnable
  19. //其本质也是发送的一个message对象
  20. private void handler1() {
  21. handler.post(new Runnable() {
  22. @Override
  23. public void run() {
  24. textView.setText("ok");
  25. }
  26. });
  27. }
  28. //第二种 handler send message
  29. private void handler2() {
  30. handler.sendEmptyMessage(1);
  31. }
  32. //第三种 runOnUiThread
  33. private void updateUI(){
  34. runOnUiThread(new Runnable() {
  35. @Override
  36. public void run() {
  37. textView.setText("okokok");
  38. }
  39. });
  40. }
  41. //第四种 view post runnable
  42. private void viewUI(){
  43. textView.post(new Runnable() {
  44. @Override
  45. public void run() {
  46. textView.setText("okokokok");
  47. }
  48. });
  49. }
  50. @Override
  51. protected void onCreate(@Nullable Bundle savedInstanceState) {
  52. super.onCreate(savedInstanceState);
  53. setContentView(R.layout.activity_handler);
  54. textView = findViewById(R.id.tv_handler);
  55. new Thread() {
  56. @Override
  57. public void run() {
  58. super.run();
  59. try {
  60. Thread.sleep(2000);
  61. //handler1();
  62. //handler2();
  63. //updateUI();
  64. viewUI();
  65. } catch (InterruptedException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. }.start();
  70. }
  71. }

以上四种方式其本质其实都是通过handler发送message去通知UI线程更新UI

直接在子线程更新UI

  1. public class ThreadActivity extends Activity {
  2. private TextView textView;
  3. @Override
  4. protected void onCreate(@Nullable Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_handler);
  7. textView = findViewById(R.id.tv_handler);
  8. new Thread() {
  9. @Override
  10. public void run() {
  11. super.run();
  12. textView.setText("1111");
  13. //try {
  14. // Thread.sleep(2000);
  15. // textView.setText("1111");
  16. // } catch (InterruptedException e) {
  17. // e.printStackTrace();
  18. // }
  19. }
  20. }.start();
  21. }
  22. @Override
  23. protected void onResume() {
  24. super.onResume();
  25. }
  26. }

这段代码执行下来是可以执行的。但是如果在子线程中执行线程休眠的方法,就会爆出  android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.异常。其根本原因在于android实现更新UI的对象。ViewRootImpl是在onResume方法中去初始化的,由于会先执行onCreate方法,所以此时的viewRootImpl还没有被初始化。 
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/98861
推荐阅读
相关标签
  

闽ICP备14008679号