在android平台下,进行多线程编程时,经常需要在主线程之外的一个单独的线程中进行某些处理,然后更新用户界面显示。但是,在主线线程之外的线程中直接更新页面显示的问题是:系统会报这个异常,android.view.viewroot$calledfromwrongthreadexception: only the original thread that created a view hierarchy can touch its views. (只有原始创建这个视图层次(view hierachy)的线程才能修改它的视图(view)。)。
也就是说必须在程序的主线程(也就是ui线程)中进行更新界面显示的工作。可以采用下面的方法之一来解决:
解决方案1:在activity.oncreate(bundle savedinstancestate)中创建一个handler类的实例, 在这个handler实例的handlemessage回调函数中调用更新界面显示的函数。例如:
- public class ExampleActivity extends Activity {
- Handler h = null;
- @override
- public void onCreate(Bundle savedinstancestate){
- h = new Handler(){
- @override
- public void handleMessage(Message msg){
- // call update gui method.
- }
- };
- }
- }
在其它的函数中,利用 send族或post族函数向这个h发送或邮寄消息即可。
解决方案2:利用activity.runonuithread(runnable)
把更新ui的代码创建在runnable中,然后在需要更新ui时,把这个runnable对象传给activity.runonuithread(runnable)。 这样runnable对像就能在ui程序中被调用。
注意,在这个地方的runnable其实不是动态的更新,如果在oncreate中使用这个方法,那么界面不会显出出来,因为需要等待runnable的方法调用完成之后,才可以进行显示界面。所以通过初始化界面来获得网络数据的情况,直接使用这个方法不可取。。。
如下:
- class Test implements Runnable
- {
- @Override
- public void run()
- {
- int len = 3;
- int i=0;
- while (i < len)
- {
- System.out.println("ljz");
- i++;
- textView.setText("Hello | " + System.currentTimeMillis());
- textView.invalidate();
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
在主界面进行如下调用:
MainActivity.this.runOnUiThread(test);
这样的结果就是创建oncreate的方法时间变大