Android:CalledFromWrongThreadException

来源:互联网 发布:js修改sass变量 编辑:程序博客网 时间:2024/06/10 23:59

一,更新UI界面

1.1 基本修改组件内容

public class MainActivity extends Activity {public TextView mTextTitle; @Overrideprotected void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);           setContentView(R.layout.activity_main);             mTextTitle = (TextView) findViewById(R.id._title);           mTextTitle.setText("HelloWorld");}  }

   布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent">    <TextView        android:id="@+id/_title"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/hello_world" /></RelativeLayout>

    在OnCreate()方式中通过mTextTitle.setText("HelloWorld");来修改组件内容。

1.2 子线程中修改UI界面

    程序有时会通过线程来进行一些任务,同时需要将结果显示在UI界面。

public class MainActivity extends Activity {public TextView mTextTitle; @Overrideprotected void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);           setContentView(R.layout.activity_main);             mTextTitle = (TextView) findViewById(R.id._title);           thread.start();}   Thread thread = new Thread() {@Overridepublic void run() {int count = 0;for (int i = 0; i < 10; i++) {count ++;}mTextTitle.setText("Sum:" + count);}};}

  使用上面代码修改UI界面会报错。运行时提示错误:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.解释:Android不允许在子线程修改UI界面,只允许在UI主线程修改UI界面。

1.3 使用Handler通过UI主线程修改界面

public class MainActivity extends Activity {public static final int C_MSG = 100;public TextView mTextTitle; @Overrideprotected void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);           setContentView(R.layout.activity_main);             mTextTitle = (TextView) findViewById(R.id._title);           thread.start();}  Thread thread = new Thread() {@Overridepublic void run() {int count = 0;for (int i = 0; i < 10; i++) {count ++;}Message msg = Message.obtain();msg.what = C_MSG;msg.arg1 = count;handler.sendMessage(msg);// mTextTitle.setText("Sum:" + count);}};Handler handler = new Handler(new Callback() {@Overridepublic boolean handleMessage(Message msg) {int what = msg.what;switch (what) {case C_MSG:int count = msg.arg1;mTextTitle.setText("Sum:" + count);break;}return false;}});}

根据如上代码:通过Handler和消息机制,在UI主线程中修改了TextView的内容。其中使用Handler和Message。有一点可以注意,Message的创建是使用Message msg = Message.obtain();为什么要这么过去对象?

1.4 其他修改UI界面方式

    1.4.1 在子线程中通过runOnUiThread()方法更新UI  

new Thread() {@Overridepublic void run() {runOnUiThread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubmTextTitle.setText("HelloWorld--runOnUiThread");}});}}.start();

    1.4.2 View.post(Runnable r)

mTextTitle.post(new Runnable() {@Overridepublic void run() {mTextView.setText("HelloWorld--View.post()");}});



0 0