Android只有主线程才能更新UI?
来源:互联网 发布:大数据登录页面素材 编辑:程序博客网 时间:2024/04/30 01:55
以前在做安卓程序开发的时候,心中有一目标——更新UI只能在主线程。这个思想或许是许多安卓开发者都觉得应该是这样,事实Google也建议我们这样做,它提供了Handler机制,通过传递Message实现主线程与子线程之间的通信。
那依据上面据所说,我们来做一个测试。先看下面代码,就是在SetContentView中设置一个TextView,并开启一个线程来是更新TextView的内容。
public class MainActivity extends AppCompatActivity { private TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mTextView = new TextView(this); mTextView.setText("旧内容"); setContentView(mTextView); new Thread(new CThread()).start(); } class CThread implements Runnable { @Override public void run() { mTextView.setText("新内容"); } }}
看到这段代码,很多人看后会说,程序肯定会Crash,因为我们子线程中直接更新UI了,这是“犯法”的事,我们运行程序看一下结果:
从图中可以看到,程序正常运行,没有Crash,并正确更新了UI,到这里也许有会有点迷惑,但确实更新了,这点我没有太了解,猜测应该是跟CPU时间片有关。这时候我们再在子线程里做一些事情,比如休眠100毫秒,这时运行程序会发现程序Crash了。并抛出一个运行时异常:ViewRootImpl$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.这个异常的意思,只有创建这个视图层次结构的原始线程才能更改它的view。这句话中可以读出一个意思,即更新UI并不一定要在主线程,只要在创建UI的那个线程中,就可以更新线程。下面再写一个例子来验证一下:
public class SecondActivity extends AppCompatActivity { TextView mMainThreadTextView; TextView mChildThreadTextView; private CHandler mUpdateHandler = new CHandler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mMainThreadTextView = new TextView(this); mMainThreadTextView.setText("主线程TextView"); setContentView(mMainThreadTextView); new Thread(new CThread()).start(); } class CThread implements Runnable { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } mChildThreadTextView = new TextView(SecondActivity.this); mChildThreadTextView.setText("子线程创建UI并更新"); Message message = mUpdateHandler.obtainMessage(); message.sendToTarget(); } } class CHandler extends Handler { @Override public void handleMessage(Message msg) { setContentView(mChildThreadTextView); super.handleMessage(msg); } }
这个例子也很简单,即在子线程中创建一个TextView,并且为这个TextView赋值,然后发送消息在Handler里面设置View,先来看一下运行结果 :
最终发现,子线程成功更新TestView的值,这就验证了Only the original thread that created a view hierarchy can touch its 这句话。也就是更新UI只要在创建UI的线程中就可以了,我们通常初始化View的时候, 一般是在OnCreate方法里面,也可以说是主线程中,所以会形成一个思维,线程更新UI只能在主线程。
当然通常我们很少在子线程中创建View,所以正常情况都还是子线程处理耗时操作,操作完毕发送Message给Handler处理。
- Android只有主线程才能更新UI?
- 【小学生学Android(1)】我们来谈谈Android的线程安全以及只有主线程才能修改UI
- Android之UI主线程更新问题
- Android 更新UI 只能在主线程?
- Android非主线程更新UI
- 在主线程更新UI
- iOS主线程更新UI
- iOS 主线程更新UI
- Android中通过其他线程更新主线程UI
- Android中通过其他线程更新主线程UI
- Android Activity sleep 自线程更新主线程UI
- Android子线程更新UI主线程方法之Handler
- Android子线程更新UI主线程方法之Handler
- 【Android】几种子线程更新UI主线程的方法
- 【Android和iOS】快速切换到主线程更新UI
- android线程间通信和主线程更新ui
- 在Android中,非主线程不能更新UI
- Android 在子线程中更新主线程UI
- JavaScript高级程序设计学习笔记——引用类型1
- Service基础
- 登录注册模块解决方案
- Javascript 严格模式详解
- 程序中调用高德地图
- Android只有主线程才能更新UI?
- [数组]面试题9 最大连续子串
- Spring+Hibernate+SpringMVC+MySql实现配置多个数据源!
- hdu 1255(线段树+离散化)
- PHP模拟守护进程
- Android第二天
- Allegro 出焊接坐标文件最新
- Java抓取网页数据(原网页+Javascript返回数据)
- sql 中的 group by 语句的作用到底是什么啊