从另一个线程更新UI

时间:2012-04-24 01:30:24

标签: android

我知道禁止从另一个线程更新UI,所以我试着看看我将从应用程序获得什么结果。是的,更新UI组件时应用程序会崩溃,但有一个案例我不明白,应用运行正常。

1)

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv = (TextView)findViewById(R.id.textView1);
        bt = (Button)findViewById(R.id.button1);

        new Thread(){ //1                       
            public void run() {                             
                tv.setText("changed");                      
        }}.start(); //1  }  
    }

2)

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv = (TextView)findViewById(R.id.textView1);
        bt = (Button)findViewById(R.id.button1);

        bt.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View arg0) {
                 new Thread(){ //1                       
                        public void run() {                             
                            tv.setText("changed");                      
                    }}.start(); //1  }  
            }

        });


    }

对于我之前对我的问题的描述感到抱歉,我想大多数人都误解了它,所以我重新解释了这个问题。上面有2个场景,它们应该给我崩溃错误,因为它们都创建新线程并更新UI组件,但事实上,只有第二个场景崩溃但fisrt场景不会崩溃。有人知道原因吗?

3 个答案:

答案 0 :(得分:2)

检查此异常

E/AndroidRuntime( 7652): FATAL EXCEPTION: Thread-19449
E/AndroidRuntime( 7652): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
E/AndroidRuntime( 7652):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4357)
E/AndroidRuntime( 7652):    at android.view.ViewRootImpl.invalidateChild(ViewRootImpl.java:802)
E/AndroidRuntime( 7652):    at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:851)
E/AndroidRuntime( 7652):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:4312)
E/AndroidRuntime( 7652):    at android.view.View.invalidate(View.java:8603)
E/AndroidRuntime( 7652):    at android.view.View.invalidate(View.java:8554)

仅在无效(呈现)时间中检查UI线程检查。
所以在创建时间(onCreate)中,没有问题。

您可以在setText之前添加Thread.sleep(5000),并且会发生上述异常。

答案 1 :(得分:0)

检查出来

private void startthread() {
anihandler = new Handler() {

@Override
public void handleMessage(Message msg) {
    super.handleMessage(msg);

     tv.setText("changed");
}

};

aniThread = new Thread() {
  public void run() {
 sleep(1000);
                 anihandler.sendMessage(anihandler
                        .obtainMessage());


}
};

aniThread.start();
}

答案 2 :(得分:0)

而不是线程,使用asynctask进行此类操作。它全部描述为here并且非常易于使用。