没有错误"只有创建视图层次可以触摸其观点和QUOT原来的线程;视图时无延迟更新 [英] No error "Only the original thread that created a view hierarchy can touch its views" when the view is updated without delay

查看:151
本文介绍了没有错误"只有创建视图层次可以触摸其观点和QUOT原来的线程;视图时无延迟更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临着一个有趣的问题。如果你写了以下code。在的onCreate / ONSTART / onResume 活动的方式:

I was faced with an interesting problem. If you write the following code in the onCreate/onStart/onResume method of activity:

final Button myButton = (Button)findViewById(R.id.myButton);
final TextView myTextView = (TextView)findViewById(R.id.myTextView);
final Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        myTextView.setText("Hello text");
    }
});
myButton.setOnClickListener(new OnClickListener() {
    @Override
        public void onClick(View v) {
        thread.start();
    }
});

final TextView myTextView = (TextView)findViewById(R.id.myTextView);
final Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            Thread.currentThread().sleep(500);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        myTextView.setText("Hello text");
    }
});
thread.start();

应该的,抛出一个错误

how it should be, an error is thrown

android.view.ViewRoot $ CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views."

重要的是,在这种情况下,我必须更新UI线程的观点 (处理器,AsyncTask的,runOnUiThread,view.post)。显然

但是,如果你更新另外一个线程视图无延迟(不睡觉打电话或不启动线程由pressing一个按钮),异常不会被抛出

But if you update the view in another thread without delay (without sleep calling or without starting the thread by pressing a button), exception will not be thrown.

final TextView myTextView = (TextView)findViewById(R.id.myTextView);
final Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        myTextView.setText("Hello text");
    }
});
thread.start();

谁能告诉我,为什么会有这样的行为?

Can anybody tell me why there is such a behavior?

更新:

我已经学会了Android的源$ C ​​$ c和来到了以下结论。    Nandeesh写的事实。 当初始化所谓dispatchAttachedToWindow查看(AttachInfo信息,INT可见性)方法的观点,初始化mAttachInfo领域。 mAttachInfo对象mViewRootImpl领域。如果为null,get​​ViewRootImpl将返回空值:

I have learned the source code of Android and came to the following conclusions. Nandeesh wrote the truth. When initializing the view called dispatchAttachedToWindow (AttachInfo info, int visibility) method of View, which initializes the mAttachInfo field. mAttachInfo object has mViewRootImpl field. If it is null, getViewRootImpl will returned as null:

public ViewRootImpl getViewRootImpl() {
        if (mAttachInfo != null) {
            return mAttachInfo.mViewRootImpl;
        }
        return null;
    }

ViewRootImpl包含checkThread方法。它比较线程:创建的视图更新请求的观点和线程的线程。

ViewRootImpl contains checkThread method. It compares threads: the thread that created the view and thread of the request for the view update.

 void checkThread() {
        if (mThread != Thread.currentThread()) {
            throw new CalledFromWrongThreadException(
                    "Only the original thread that created a view hierarchy can touch its views.");
        }
    }

因此​​,如果认为没有初始化,没有检查和更换不抛出异常。

Thus, if the view was not initialized, there is no check and change do not throws exceptions.

推荐答案

在检查线程是present只有当的TextView 重新布局完成。但是,鉴于布点只在的OnCreate 被称为完成。所以直到UI未示出,改变的TextView的不会造成无效的视图的

The check for thread is present only if textView relayout is done. But the Layouting of the view is only done after OnCreate is called . So till the Ui is not shown, changing of textView will not result in invalidating of the view.

但是,一旦TextView的已经显示,用户界面​​重布局是必需的,在这种情况下,该线程被检查。所以你只有在OnCreate中的一些时间,但得到的异常不会立即进行。

But once the textView has been shown, the UI relayout is required, in which case the thread is checked. So you get the exception only after some time of Oncreate but not immediately.

这篇关于没有错误"只有创建视图层次可以触摸其观点和QUOT原来的线程;视图时无延迟更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆