UI更新的方法和在非UI线程里面,怎么更新UI信息。细细的

更新UI的几种方式:
runOnUiThread;
Handler post;
handler sendMessage;
view post;
第一种方法:Handler post:
public class FiveActivity  extends Activity {
    private TextView  textView ;
    private Handler  handler new Handler() ;

    @Override
    protected void  onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState) ;
        setContentView(R.layout. five) ;
        textView = (TextView) findViewById(R.id. tv1) ;
        new Thread() {
            @Override
            public void  run() {
                try {
                    Thread. sleep( 3000) ;
               catch (InterruptedException e) {
                    e.printStackTrace() ;
                }
                handler.post( new Runnable() {
                    @Override
                    public void  run() {
                        textView.setText( "更新完成") ;
                    }
                }) ;
            }
        }.start() ;
    }
}    
理解:程序运行,然后直走,进入线程UI线程显示当前内容,子线程等待,然后通过,handler.post更新显示内容(在主线程中执行);
第二种方法handler sendMessage :
public class FiveActivity  extends Activity {
    private TextView  textView ;
    private Handler  handler new Handler() {
        @Override
        public void  handleMessage(Message msg) {
            super.handleMessage(msg) ;
            textView.setText( "更新完成") ;
           
        }
    } ;

    private void  handler2(){
        handler.sendEmptyMessage( 1) ;
    }
    @Override
    protected void  onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState) ;
        setContentView(R.layout. five) ;
        textView = (TextView) findViewById(R.id. tv1) ;
        new Thread() {
            @Override
            public void  run() {
                try {
                    Thread. sleep( 3000) ;
                    handler2() ;
               catch (InterruptedException e) {
                    e.printStackTrace() ;
                }

            }
        }.start() ;
    }
}
理解:程序运行,UI线程显示当前内容,子线程运行到handler.sendEmptyMessage(1)时候,给handler发送指令,然后更新完成。其中testView.setText在主线程中运行,其他步骤在子线程中运行。
第三种方法runOnUiThread :
    private void  update(){
        runOnUiThread( new Runnable() {
            @Override
            public void  run() {
                textView.setText( "更新完成") ;
                Log. d( "test" "线程:" + Thread. currentThread()) ;
            }
        }) ;
    }
    @Override
    protected void  onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState) ;
        setContentView(R.layout. five) ;
        textView = (TextView) findViewById(R.id. tv1) ;
        new Thread() {
            @Override
            public void  run() {
                try {
                    Thread. sleep( 3000) ;
                    update() ;
               catch (InterruptedException e) {
                    e.printStackTrace() ;
                }

            }
        }.start() ;
    }
}
理解:程序运行——>执行子线程——>执行到update方法的时候,UI更新;(testView.setText在主线程中运行)
第四种方法view post :
  private void  viewUI(){
        textView.post( new Runnable() {
            @Override
            public void  run() {
                textView.setText( "更新完成") ;
                Log. d( "test" "线程:" + Thread. currentThread()) ;
            }
        }) ;
    }
    @Override
    protected void  onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState) ;
        setContentView(R.layout. five) ;
        textView = (TextView) findViewById(R.id. tv1) ;
        new Thread() {
            @Override
            public void  run() {
                try {
                    Thread. sleep( 3000) ;
                    viewUI() ;
               catch (InterruptedException e) {
                    e.printStackTrace() ;
                }

            }
        }.start() ;
    }
}
理解:程序运行——>执行子线程——>执行到viewUI方法的时候,UI更新;(testView.setText在主线程中运行)


非UI线程更新UI的方法:
     
public class SixActivity  extends Activity {
    private TextView  textView ;

    @Override
    protected void  onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState) ;
        setContentView(R.layout. six) ;
        textView= (TextView) findViewById(R.id. textView2) ;
        new Thread(){
            @Override
            public void  run() {
                textView.setText( "就更新你了,咋地") ;
                Log. d( "test" , "线程:"+Thread. currentThread()) ;
            }
        }.start() ;
    }
}
  对,这就是非UI线程更新UI的方法,什么都别加 ,赤裸裸的。但是这是为什么呢,我们就一起去看看吧!
我们都知道,所有更新UI的方法,都会调用view的invalidate方法;
public void  invalidate() {
    invalidate( true) ;
}
void  invalidate( boolean invalidateCache) {
    invalidateInternal( 0 0 mRight mLeft mBottom mTop invalidateCache , true) ;
}

void  invalidateInternal( int l , int t , int r , int b , boolean invalidateCache ,
        boolean fullInvalidate) {
    if ( mGhostView !=  null) {
        mGhostView.invalidate( true) ;
        return;
    }

    if (skipInvalidate()) {
        return;
    }

    if (( mPrivateFlags & ( PFLAG_DRAWN PFLAG_HAS_BOUNDS)) == ( PFLAG_DRAWN PFLAG_HAS_BOUNDS)
            || (invalidateCache && ( mPrivateFlags PFLAG_DRAWING_CACHE_VALID) ==  PFLAG_DRAWING_CACHE_VALID)
            || ( mPrivateFlags PFLAG_INVALIDATED) !=  PFLAG_INVALIDATED
            || (fullInvalidate && isOpaque() !=  mLastIsOpaque)) {
        if (fullInvalidate) {
            mLastIsOpaque = isOpaque() ;
            mPrivateFlags &= ~ PFLAG_DRAWN ;
        }

        mPrivateFlags |=  PFLAG_DIRTY ;

        if (invalidateCache) {
            mPrivateFlags |=  PFLAG_INVALIDATED ;
            mPrivateFlags &= ~ PFLAG_DRAWING_CACHE_VALID ;
        }

        // Propagate the damage rectangle to the parent view.
        final AttachInfo ai =  mAttachInfo ;
        final ViewParent p =  mParent ;
        if (p !=  null && ai !=  null && l < r && t < b) {
            final Rect damage = ai. mTmpInvalRect ;
            damage.set(l t r b) ;
            p.invalidateChild( this, damage) ;
        }

        // Damage the entire projection receiver, if necessary.
        if ( mBackground !=  null &&  mBackground.isProjected()) {
            final View receiver = getProjectionReceiver() ;
            if (receiver !=  null) {
                receiver.damageInParent() ;
            }
        }

        // Damage the entire IsolatedZVolume receiving this view's shadow.
        if (isHardwareAccelerated() && getZ() !=  0) {
            damageShadowReceiver() ;
        }
    }
}
     其中关键的是ViewParent。然后,在ViewParent里面有个叫做InvalidateChildlnParent的方法,在这个方法中呢,有个checkThread的方法,这个就是拿来检查线程的;他的工作原理:在他的方法里面,会有一个判断,也就是
     if(mThread!=Thread.curremtThread){
          throw new Call………………………………(太长了,不想打了,就是用子线程更新UI而看到的异常。)
}
那么问题来了,当前线程没有休眠的时候呢,为什么就可以更新线程了呢?
那是因为Activity有个 ViewRootImpl他在onResume中创建,因为程序先走的是onCreate,所以,这ViewRootImpl 还没有被创建出来,也就不会进行
checkThread的判断拉,所以就不会报错了呢。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值