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

原创 2016年06月01日 22:29:48
更新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(00mRight mLeftmBottom mTopinvalidateCache, 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(ltrb);
            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的判断拉,所以就不会报错了呢。
版权声明:本文为博主原创文章,未经博主允许不得转载。

android 在非UI线程更新UI仍然成功原因深入剖析

转载:http://blog.csdn.net/zhaokaiqiang1992/article/details/43410351 ”只能在UI主线程中更新View“。     这句话...
  • qq_30651537
  • qq_30651537
  • 2016年05月24日 11:34
  • 1383

Android 中非UI线程真的不能更新UI吗?

更新UI需要UI线程,主线程就是一个UI线程。因为还可以创建很多UI线程,所以不只有主线程才能更新UI。 但是一般的子线程是不能更新UI的。本文中提到的“一般的子线程”处于一个特殊的位置,所以才更新了...
  • u013806583
  • u013806583
  • 2016年11月22日 23:42
  • 382

为什么我们可以在非UI线程中更新UI

看到这样的标题……估计N多人会说我是逗比…………因为很多盆友在学习Android(特别是从4.0之后开始入门的)的时候都会常看见或听到别人说我们更新UI呢要在UI线程(或者说主线程)中去更新UI,不要...
  • aigestudio
  • aigestudio
  • 2015年02月03日 14:11
  • 20458

子线程中更新UI的几种方法

UI一般只能在主线程(UI线程),更新,如果要在子线程更新的话怎么办? 总结了一下大概有下面五种方式: 1.使用runOnUiThread() 示例代码: new Thread() {   publ...
  • xx_dd
  • xx_dd
  • 2016年10月21日 23:42
  • 1447

C#子线程更新UI控件的方法实例总结

本文实例总结了C#子线程更新UI控件的方法,对于桌面应用程序设计的UI界面控制来说非常有实用价值。分享给大家供大家参考之用。具体分析如下: 一般在winform C/S程序中经常会在子线程中更新控件...
  • rattles
  • rattles
  • 2016年06月27日 20:34
  • 1475

C#子线程中更新ui

这篇文章主要介绍了C#子线程更新UI控件的方法,在桌面应用程序中控制UI界面有着不错的实用价值,需要的朋友可以参考下。 本文实例总结了C#子线程更新UI控件的方法,对于桌面应用程序设计的UI界面...
  • yxtouch
  • yxtouch
  • 2015年08月17日 14:44
  • 2615

Android 在子线程中更新UI的3种方法

第一种:new Handler(context.getMainLooper()).post(new Runnable() { @Override public void run() {...
  • u010507199
  • u010507199
  • 2017年05月03日 10:50
  • 1435

Android在子线程中更新UI的方法汇总(共七种)

1、常规写法:new Handler()的handleMessage()和handler.sendMessage(msg) 2、handler的另一种用法: 3、handler.post(runn...
  • qq_26287435
  • qq_26287435
  • 2017年03月23日 20:50
  • 396

android中子线程更新UI的方式浅析

一、为何写作此文  你是不是经常看到很多书籍中说:不能在子线程中操作ui,不然会报错。你是不是也遇到了如下的疑惑(见下面的代码):@Override protected void onCr...
  • a910626
  • a910626
  • 2015年05月23日 23:44
  • 3615

Android更新Ui的几种方法和见解

先贴一个我们刚做Android开发时候最容易遇到的一个错误异常 AndroidRuntimeException :“Only the original thread that created a vi...
  • u011254308
  • u011254308
  • 2015年04月18日 19:29
  • 9227
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UI更新的方法和在非UI线程里面,怎么更新UI信息。细细的
举报原因:
原因补充:

(最多只允许输入30个字)