package NotUIThread_UpdateNotWrong.sonyChinaese.run;import mythread.UpdateTextViewThread;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;public class Main extends Activity {
private TextView textView1; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView1 = (TextView) this.findViewById(R.id.textView1); Log.v("!Main", "" + Thread.currentThread().getName() + " "
+ Thread.currentThread().getId()); UpdateTextViewThread mythread = new UpdateTextViewThread();
mythread.setTextView1(textView1);
mythread.start(); }
}
----------
package mythread;import android.util.Log;
import android.widget.TextView;public class UpdateTextViewThread extends Thread { private TextView textView1; public void setTextView1(TextView textView1) {
this.textView1 = textView1;
} @Override
public void run() {
super.run();
Log.v("!run", "" + Thread.currentThread().getName() + " "
+ Thread.currentThread().getId());
textView1.setText("aaaaaaaaaaaaaaaaaaaa");
}
}

解决方案 »

  1.   

    不能sleep,还只能放在onCreate里面做,其实意义不大,等大牛解释
      

  2.   

    本来就是能更新view的啊。。
    就是容易出现卡机现象。。
      

  3.   

    肯定会报异常的,难道现在Android可以使用多线程更新UI控件了?
      

  4.   

    你在线程里加个sleep(2000),或者把Thread放到 onStart里,你看会不会出错。还是好好研究下Activity生命周期吧。各个周期明白都干了什么你就知道为什么不出错了。
      

  5.   

    因为你的textview在settext的时候还没有显示,整个activity大概还没有进入onstart阶段。你弄个循环在textview已经显示了之后再修改试试
      

  6.   

    经测试,可以在非主线程里面对界面信息进行设置,但是:非主线程不能直接刷新主线程的界面,否则就会报异常android.view.ViewRoot$CalledFromWrongThreadException。
    贴上测试代码:
    protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    new Thread() {
    public void run() {
    super.run();
    TextView tx = (TextView) findViewById(R.id.textView);
    tx.setText("lllllllllllllllllllll");
    } }.start(); Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new OnClickListener() { @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
    new Thread() {
    public void run() {
    super.run();
    TextView tx = (TextView) findViewById(R.id.textView);
    tx.setText("2222222222222");
    } }.start();
    }
    });
    }
      

  7.   

    注:这段代码是在setContentView()之后;当点击button后才会报错
      

  8.   

       其实在后台线程中访问UI控件本来就是不一定报错的。
        但是在操作的过程中,比较容易发生异常,而导致程序变得很卡(变得很卡是没有调试器连接的情况,如果程序是在调试状态运行,那么这个时候eclipse会告诉你发生了CalledFromWrongThreadException),这个概率么,说不上来,但是如果后台线程如果是循环执行这个访问操作就很容易遇到。
        像楼主这种只执行一次的情况,遇到的概率不高。
      

  9.   

    protected void onStart() {
    // TODO Auto-generated method stub super.onStart(); TextView tx = (TextView) findViewById(R.id.textView);
    tx.setText("aaaaaaaaaaa"); new Thread() {
    public void run() {
    super.run();
    TextView tx = (TextView) findViewById(R.id.textView);
    for (int i = 0; i < 3; i++) {
    tx.setText("lllllllllllllllllllll" + i);
    }
    } }.start(); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
    new Thread() {
    public void run() {
    super.run();
    TextView tx = (TextView) findViewById(R.id.textView);
    tx.setText("2222222222222");
    } }.start();
    }
    });
    }结论一样,只有在点击按钮之后才报错
      

  10.   


    nonono,当我点击按钮之后是100%报错的
      

  11.   

    咋能说木有意义呢,可以增加对Activity的了解嘛。我的理解是:非主线程可以对界面信息进行更新,但是不能进行刷新。在Activity执行完onResume()之前,界面实际上是没画好的,所以可以随便进行更新。执行完onResume()之后,界面就算画好了,这时候刷新界面的事情只能让ui线程干了。对or错?
      

  12.   

    跟:
    runOnUiThread(new Runnable{
        public void run(){
          text.setText("---");
        }
    });有区别吗 ??
      

  13.   

    Android提供了UI线程 ,最好不要在 线程里面更新UI,,这样做不保险。。做实际的项目千万别做就好。
      

  14.   

    the Andoid UI toolkit is not thread-safe. So, you must not manipulate your UI from a worker thread
      

  15.   

    用handler不行么? 我就是这么用的 就是在页面显示出来之后再来动态的改变ui 实际改变的代码还是放在ui线程里面
    package com.hundsun.zhoujl.android;import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.widget.TextView;public class TestUIChangeActivityActivity extends Activity {

    private TextView tv = null;
    private Handler handler = null;

    @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            tv = (TextView)findViewById(R.id.tv);
            handler = new Handler() { @Override
    public void handleMessage(Message msg) {
    super.handleMessage(msg);
    tv.setText("Hello Handler");
    }
            
            };
            Thread thread = new Thread() { @Override
    public void run() {
    super.run();
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    handler.sendEmptyMessage(0);
    }
            
            };
            thread.start();
        }
    }
      

  16.   

    这个答案比较贴近,我记得在一篇介绍handler looper messagequeue的文章中讲过,在OnCreate这个事件中其他线程是可以更新UI的,但在其他On中就一定会报错
      

  17.   

    View不是线程安全的吧。会有data racing的问题。多线程编程,最基本的问题就是同步加锁等解决data race。 当然data race的时候,大部分情况下不会死,也可能会做对,但由于两个线程间互相不知道对方对自己要管理的资源做了什么手脚,会出现很多奇怪的问题。
      

  18.   

    可以但是会出现问题,因为View不是线程安全
      

  19.   

    摆脱你的UpdateTextViewThread  也是UI线程,
    你不会以为 UI线程就是看不见的吧看不见的线程,但拥有的 View组件的也算 UI线程好不好
      

  20.   

    可以看下源码 
    View 的线程检测机制在ViewRootIml类的checkThread()方法中,
    void checkThread() {
            if (mThread != Thread.currentThread()) {
                throw new CalledFromWrongThreadException(
                        "Only the original thread that created a view hierarchy can touch its views.");
            }
        }ViewRootIml是接口ViewParent的实现,它会在requestFitSystemWindows()、requestLayout()、invalidateChildInParent(int[] location, Rect dirty)、requestTransparentRegion(View child)、requestChildFocus(View child, View focused)、clearChildFocus(View child)、focusableViewAvailable(View v)、recomputeViewAttributes(View child)、playSoundEffect(int effectId)、focusSearch(View focused, int direction)、doDie()方法中进行检查的
    View中大部分方法都是基于ViewParent(指向ViewRootIml的引用),这个检测机制在某个特定的条件下是不会检查的~