Android Thread修改EditText
我在修改由线程启动的另一个函数中的EditText时遇到问题:
Thread thRead = new Thread( new Runnable(){ public void run(){ EditText _txtArea = (EditText) findViewById(R.id.txtArea); startReading(_txtArea); } });
我的function如下:
public void startReading(EditText _txtArea){ _txtArea.setText("Changed"); }
在尝试修改edittext时,它总是强制关闭。 有人知道为什么吗?
不应从非UI线程修改UI视图。 唯一可以触及UI视图的线程是“主”或“UI”线程,调用onCreate()
, onStop()
和其他类似的组件生命周期函数。
因此,每当您的应用程序尝试从非UI线程修改UI视图时,Android会抛出一个早期exception,以警告您不允许这样做。 这是因为UI不是线程安全的,这样的早期警告实际上是一个很棒的function。
更新:
您可以使用Activity.runOnUiThread()
来更新UI。 或者使用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"); } });
首先看看你的日志,它通常包含一个应用程序关闭时的堆栈跟踪。
你不应该像平常那样运行线程,而是使用runOnUiThread
:
Runnable thRead = new Runnable(){ public void run() { EditText _txtArea = (EditText) findViewById(R.id.txtArea); startReading(_txtArea); } }; runOnUiThread(thRead);
解释:只允许UI线程更改UI组件的状态。
本文可能对您有所帮助。
http://android-developers.blogspot.com/2009/05/painless-threading.html
选择很少:
1.在UI线程上运行它Activity.runOnUiThread(Runnable)
2.使用AsyncTask
除了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);
默认情况下,主线程是UI线程。 修改应用程序外观的所有代码都需要在此线程中运行。 如果你想在你的应用程序中有多个可以修改UI的线程,我建议使用AsyncTask类。
public someMethod(){ new ChangeTextTask().execute(); } private class ChangeTextTask extends AsyncTask { @Override protected Void doInBackground(Void... params) { startReading(_txtArea); return null; } }
但是,您需要采取措施防止多个线程一次访问EditText对象。 否则你最终会收到CurrentModificationException错误。
http://developer.android.com/reference/android/os/AsyncTask.html