非UI线程是没有更新UI的权限的。

解决方案 »

  1.   

    - -第一个能更新么~ 想看看你怎么写的。~ 非UI线程更新UI会报错的
      

  2.   

    顶一下!
    发一下代码:
    package extthread;import android.widget.TextView;public class MyUpdateUIThread extends Thread { private TextView textView1; public MyUpdateUIThread(TextView textView1) {
    super();
    this.textView1 = textView1;
    } @Override
    public void run() {
    super.run();
    textView1.setText("zzzzzzzzzzzzzz");
    }}------------------------------
    package testtest.test.run;import android.app.Activity;
    import android.os.Bundle;
    import android.widget.TextView;
    import extthread.MyUpdateUIThread;public class Main extends Activity {
    TextView textView; @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); textView = (TextView) this.findViewById(R.id.textView1);
    Thread thread = new Thread(new MyUpdateUIThread(textView));
    thread.start(); }
    };上面用线程代码不出错!
      

  3.   

    只能在主线程中操作UI。
    所以如果你想在非主线程中操作UI,就要在使用消息发送的方式。例:
    在主线程中定义handler:Handler h=new Handler(){
    public void handleMessage(Message msg){
    //你的操作

    }在非主线程这样使用:
    h.sendMessage(Message.obtain());  //也可以新建一个Message对象
      

  4.   


    楼上的是可以的。以至于你的代码为什么没错,估计是因为把对象传过来了,而对象是在主线程中new的。所以就可以更新了吧。
      

  5.   

    Handler h=new Handler(){
    public void handleMessage(Message msg){
    //你的操作

    }在非主线程这样使用:
    h.sendMessage(Message.obtain()); //也可以新建一个Message对象
    这种方法可行!
      

  6.   

    Thread thread = new Thread(new MyUpdateUIThread(textView));
    thread.start();
    首先看到你这样创建线程时,我震惊了~你的MyUpdateUIThread纯当实现Runnable接口的类来使用了~
    直接
    Thread thread = new MyUpdateUIThread(textView);
    thread.start();
    就好了。然后我直接测试下。。发现问题了。。
    居然真的能textView1.setText("zzzzzzzzzzzzzz");不报错。
    这太操蛋了~于是我分别在onCreate和run方法里加了打印语句Thread.currentThread().getName()
    10-31 09:55:15.348: VERBOSE/King(1228): in run : Thread-10
    10-31 09:56:33.088: VERBOSE/King(1328): in Activity : main
    明明是不同线程是确定了的~
    然后我在run方法里加了个sleep()想看看可不可以隔几秒再把“zzzzzzz”更新到UI上去,如下:
    public void run() {
    super.run();
    try {
    Thread.sleep(3000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    textView1.setText("zzzzzzzzzzzzzz");
    Log.v("King", "in run : "+Thread.currentThread().getName());
    }
    这样就出错了。
    我也纳闷了。为了不sleep能正常运行。应该是会出错的啊。
    建议没试过的童鞋都试一下。。惊天发现啊~
      

  7.   

    测试过程发现,如果这个线程是通过监听器启动的,也就是说不是在主线程中直接启动,就会报错。现在想来和java的线程触发可能有关联。
      

  8.   

    run方法的里面的sleep()抛的异常是什么?
      

  9.   

    sleep方法不会抛异常。
    textView1.setText("zzzzzzzzzzzzzz");这句才会。
    异常信息如下,大家应该曾经都见过~:
    10-31 11:47:04.118: ERROR/AndroidRuntime(3878): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.我估计是在主线程初始化界面完毕之前其他线程能改UI的内容吧...或许是在onResume执行完毕之前...像什么通过监听器触发或者sleep了几秒后,UI初始化已经完毕了,于是不能在别的线程里改了...
      

  10.   


    都是在onCreate里进行操作。都是不耗时的简单线程。这样有什么意义呢?如果你的线程在onResume之后执行,100%出错。
      

  11.   

    我也测试了一下Thread.sleep()
    这句话放到activity里面就没有问题,放到run里面就不行,求解
      

  12.   

    刚才测试了,onResume中启动线程依然没报错,挺神奇的!
      

  13.   


    不神奇。onResume之后就会报错了。比如点击button启动
      

  14.   

    在线程的run方法中使用runOnUiThread来更新TextView
    Your_Current_Activity.this.runOnUiThread(new Runnable() {
        public void run() {             //update textview here
        }
    });
    改变你的 MyUpdateUIThread 构造函数:private TextView textView1;
    Activity activity;
    public MyUpdateUIThread(TextView textView1,Activity activity) {
    super();
    this.textView1 = textView1;
    this.activity=activity;
    }@Override
    public void run() {
    super.run();
    activity.runOnUiThread(new Runnable() {
        public void run() {       //update textview here
           textView1.setText("zzzzzzzzzzzzzz");
        }
    });}
    然后在 Main Activity 中创建 MyUpdateUIThread 对象:
    Thread thread = new Thread(new MyUpdateUIThread(textView,Main.this));
     
      

  15.   

    在oncreate和onresume之前view是没有调用invalidate()方法,所以调用到ViewRoot里面的    void checkThread() {
            if (mThread != Thread.currentThread()) {
                throw new CalledFromWrongThreadException(
                        "Only the original thread that created a view hierarchy can touch its views.");
            }
        }这个方法,所以不会有异常抛出,而settext的字符已经设置进去了,在onresume后得到焦点,再invalidate()就出现了在线程设置的字符串
      

  16.   

    一般只有在Activity的onResume()回调后,才会通过UI Thread建立View 树,当然最重要的是ViewRoot对象,
    你直接通过一个线程run时,可能onResume()方法还没有回调,此时当然能调用View.setXXX(),在onResume()方法回调后,一定会报异常的
    。这样就可以解释10L同学的答案了。
      

  17.   

    .net可以通过delegate进行线程更新UI线程,java不知道怎么搞
      

  18.   


    onResume里面更新也没报错
      

  19.   


      基本原理是这样的,但由于这些行为都涉及了很多IPC操作,导致onResume()后,UI Thread建立View 树还没有成功,此时,依旧可以通过线程操作View对象了。不过View添加至窗口后,就只能在UI Thread更新了。
      

  20.   

    在子线程中除了可以改变textview,button的内容外,还有什么进度条,button,textview等等的显示(setvisibile属性),弄得我一时纳闷了,什么才是UI?不是子线程不能改变UI么?
      

  21.   


    不神奇。onResume之后就会报错了。比如点击button启动加1 , 我这样测试了下,  在UI初始化完毕之后   就不能在线程里修改了.. 
      

  22.   

    把 sleep  改成 sleep 1 看看
      

  23.   

    是不能在非ui线程里更新控件的,你百度下"Handler+Thread更新ui",网上很多的