Android Thread修改EditText

时间:2011-08-11 15:01:15

标签: java android multithreading android-edittext

我遇到了在线程启动的另一个函数中修改EditText的问题:

Thread thRead = new Thread( new Runnable(){
    public void run(){
       EditText _txtArea = (EditText) findViewById(R.id.txtArea);
       startReading(_txtArea);
    }
 });

我的功能如下:

public void startReading(EditText _txtArea){
         _txtArea.setText("Changed");
}

尝试修改edittext时始终强制关闭。有人知道为什么吗?

5 个答案:

答案 0 :(得分:5)

不应从非UI线程修改UI视图。唯一可以触及UI视图的线程是“主”或“UI”线程,即调用onCreate()onStop()和其他类似组件生命周期函数的线程。

因此,每当您的应用程序尝试从非UI线程修改UI视图时,Android会抛出一个早期异常,以警告您不允许这样做。这是因为UI不是线程安全的,这样的早期警告实际上是一个很棒的功能。


<强>更新

您可以使用Activity.runOnUiThread()更新用户界面。或者使用AsyncTask。但由于在您的情况下您需要不断从蓝牙读取数据,因此不应使用AsyncTask

以下是runOnUiThread()的示例:

runOnUiThread(new Runnable() {            
    @Override
    public void run() {
        //this will run on UI thread, so its safe to modify UI views.
         _txtArea.setText("Changed");
    }
});

答案 1 :(得分:3)

首先看看你的日志,它通常包含一个应用程序关闭时的堆栈跟踪。

您不应该像平常那样运行线程,而是使用runOnUiThread

Runnable thRead = new Runnable(){
   public void run() {
      EditText _txtArea = (EditText) findViewById(R.id.txtArea);
      startReading(_txtArea);
   }
};
runOnUiThread(thRead);

解释:只允许UI线程更改UI组件的状态。

答案 2 :(得分:1)

本文可能会对您有所帮助。

http://android-developers.blogspot.com/2009/05/painless-threading.html

选项很少:
1.在UI线程Activity.runOnUiThread(Runnable)上运行它 2.使用AsyncTask

答案 3 :(得分:1)

runOnUiThread()(有效)外,还有另一种方法,我知道:

在UI(Activity)类中定义处理程序:

public class MainActivity extends Activity {

.....

    Handler uiThreadHandler = new Handler() {
        public void handleMessage(Message msg) {
            Object o = msg.obj;
            if (o==null) o = "";
            TextView textIn = (TextView)findViewById(R.id.textin);
            textIn.setText(o.toString());
        }
    };

}

从一些线程中你可以调用它:

Message msg = uiThreadHandler.obtainMessage();
msg.obj = "Text for EditView";
uiThreadHandler.sendMessage(msg);

答案 4 :(得分:0)

默认情况下,主线程是UI线程。修改应用程序外观的所有代码都需要在此线程中运行。如果你想在你的应用程序中有多个可以修改UI的线程,我建议使用AsyncTask类。

public someMethod(){
    new ChangeTextTask().execute();
}

private class ChangeTextTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... params) {
        startReading(_txtArea);
        return null;
    }
}

但是,您需要采取措施防止多个线程一次访问EditText对象。否则你最终会收到CurrentModificationException错误。

http://developer.android.com/reference/android/os/AsyncTask.html