解决方案 »

  1.   

    setText 需要对 view 重新绘制,显示文本 而在 android 里对 view 重新进行绘制的话,需要在主线程中调用,或者使消息进入 Looper 队列
      

  2.   

    UI控件的函数setText只能在UI线程里调用,否则会导致异常。
    可以用AsyncTask来处理。
      

  3.   

    示例代码public class MainActivity extends Activity { private Button incButton;
    private TextView msgTextView;
    private int count = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    msgTextView = (TextView)findViewById(R.id.msgTextView);
    incButton = (Button)findViewById(R.id.incButton);
    incButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    AsyncTask<Void, Void, String> thread = new AsyncTask<Void, Void, String>() {
    @Override
    public String doInBackground(Void... params) {
    count++;
    return String.format("%d", count);
    }
    @Override
    public void onPostExecute(String msg) {
    msgTextView.setText(msg);
    }
    };
    thread.execute();
    }
    });
    }
    }
      

  4.   

    或者把线程封装成一个内部类,这样代码就会写得更简洁优雅:public class MainActivity extends Activity { private Button incButton;
    private TextView msgTextView;
    private int count = 0; @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    msgTextView = (TextView)findViewById(R.id.msgTextView);
    incButton = (Button)findViewById(R.id.incButton);
    incButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    new MyTask().execute();
    }
    });
    }

    private class MyTask extends AsyncTask<Void, Void, String> {
    @Override
    public String doInBackground(Void... params) {
    count++;
    return String.format("%d", count);
    }
    @Override
    public void onPostExecute(String msg) {
    msgTextView.setText(msg);
    }
    }
    }
      

  5.   

    用handler也可以解决。private int x = 0;
    private MyHandler handler =new MyHandler() ;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.hello_world_layout);
              
            Button b = (Button) findViewById(R.id.button);
            final TextView v2 = (TextView) findViewById(R.id.t2);
            new MyThread().start();
        }
    private class MyHandler extends Handler{
    @Override
    public void handleMessage(Message msg) {
    if(msg.what==100){
    v2.setText(x++ + "");
    }
    }
    }
    private class MyThread extends Thread{
    public void run() {
    while(true){
    handler.sendEmptyMessage(100);
    }
    }
    }
      

  6.   

    也可以使用handler模式,这种模式更适合于生命期较长的线程,或者线程运行过程中需要多次给UI控件发消息。
    你可以体会一下以上代码的差别和用法。public class MainActivity extends Activity { private Button incButton;
    private TextView msgTextView;
    private int count = 0;
    private Handler handler; @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    msgTextView = (TextView)findViewById(R.id.msgTextView);
    incButton = (Button)findViewById(R.id.incButton);
    incButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    new MyTask().execute();
    }
    });
    handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
    msgTextView.setText((String)msg.obj);
    }
    };
    }

    private class MyTask extends AsyncTask<Void, Void, Void> {
    @Override
    public Void doInBackground(Void... params) {
    count++;
    Message msg = handler.obtainMessage();
    msg.obj = String.format("%d", count);
    msg.sendToTarget();
    return null;
    }
    }
    }
      

  7.   

    我这个例子里同时使用了handler和AsyncTask,精妙之处就在于使用AsyncTask可以更好地接收参数。如果直接从Thread继承,就需要用类成员变量来保存传递参数了,非常的麻烦。
    android里线程的使用模式有很多,要根据具体的应用场景来分别选择,所以需要对各种模式都有所了解掌握。
      

  8.   

    v2.setText(x++ + "");UI设置要在主线程 可以用主线程的handler来发送message通知主线程来修改UI
      

  9.   


    很奇怪你为什么会在 AsyncTask 中继续调用 Handler,而不直接实现 AsyncTask 中的onPostExecute(Object o),这个方法同样能够操作 ui 线程,并且免去对 handler 的调用?
      

  10.   


    很奇怪你为什么会在 AsyncTask 中继续调用 Handler,而不直接实现 AsyncTask 中的onPostExecute(Object o),这个方法同样能够操作 ui 线程,并且免去对 handler 的调用?
    我是为了演示handler的用法。而且onPostExecute只能执行一次,而线程运行中可以利用handler可以给UI线程多次发消息,使用起来更灵活。
      

  11.   

    UI更新操作只能在主线程中也就是UI线程进行