0

我知道从另一个线程更新 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  }  
            }

        });


    }

很抱歉我之前对我的问题的描述,我认为大多数人都误解了它,所以我重新提出这个问题。上面有两种情况,它们应该给我崩溃错误,因为它们都创建新线程和更新 UI 组件,但实际上,只有第二种情况崩溃,但第一个场景没有崩溃。有人知道原因吗?

4

3 回答 3

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) 并且会发生上述异常。

于 2012-04-24T03:23:33.030 回答
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();
}
于 2012-04-24T03:08:57.997 回答
0

代替 Threading,使用 asynctask 进行这种操作。这一切都在此处进行了描述,并且非常易于使用。

于 2012-04-24T03:13:21.983 回答