子线程更新ui

When an Activity receives focus, it will be requested to draw its layout. The Android framework will handle the procedure for drawing, but the Activity must provide the root node of its layout hierarchy.

ui一般只有主线程才能更新,子线程何以直接更新ui,上面是官方文档提供的,要想重画界面,必须先提供根节点

其实在每次activity通过ui线程draw时,它都会记住当前ui线程,所以每次子线程调用更新ui时会报这样的错"Only the original thread that created a view hierarchy can touch its views."看下该异常抛出的源代码android.view.ViewRoot

    void checkThread() {

if(mThread!=Thread.currentThread()){

thrownewCalledFromWrongThreadException(

"Onlytheoriginalthreadthatcreatedaviewhierarchycantouchitsviews.");

}

    }

mThread 代表主线程,当然子线程和主线程不等,所以抛出异常,所以子线程要想更新ui,必须确保你能获取viewroot.而WindowManagerImpl便符合条件,下面是一个简单的实例

 package sanjie.test;

import android.app.Activity;

importandroid.os.Bundle;

importandroid.os.Looper;

importandroid.view.WindowManager;

importandroid.view.WindowManager.LayoutParams;

import android.widget.TextView;

public class UiandsonthreadtestActivity extends Activity {

/**Calledwhentheactivityisfirstcreated.*/

@Override

publicvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

  new Thread(new WorkThread()).start();

 }

 private class WorkThread implements Runnable {

  @Override

publicvoidrun(){

Looper.prepare();

try{

Thread.sleep(5000);

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

WindowManagermanager=UiandsonthreadtestActivity.this

.getWindowManager();

TextViewview=newTextView(UiandsonthreadtestActivity.this);

view.setText("test");

LayoutParamsparams=newLayoutParams();

params.width=WindowManager.LayoutParams.WRAP_CONTENT;

   params.height=WindowManager.LayoutParams.WRAP_CONTENT;

   System.out.println("窗口对象是--------->"

+UiandsonthreadtestActivity.this.getWindowManager());

manager.addView(view,params);

Looper.loop();

  }

 }}

通过它便可以在子线程内更新ui了

相关推荐