Android之为什么只能在UI线程操作View

很长一段时间以来,面试的时候我总喜欢问一个问题:为什么只能在UI线程对View进行操作?android程序员在涉足android开发的早期应该就有这样一个认识,但是没有多少人知道究竟是为什么。以至于后来,我也就不愿意问这个问题了,不知道这个问题的答案其实也不妨碍候选人做出好的功能。虽然感觉是很自然的事情,但是不弄清楚总觉得有些不舒服,于是,我花了点时间研究了一下。

其实这个问题的答案并不复杂,只要看一下android源码就能够定位出来。我看的是android2.3的源码,2.3系统确实显得有些过时,但是android很多基本的东西从2.3到4.0都没有发生根本性的变化(5.0没有研究过,不敢妄下断论)。

View的一些基本操作

View进行操作无非是使其可见或者不可见,给ViewGroup加一个View或移除一个View,改变View的大小等,这些操作直接或者间接地会调用到ViewinvalidaterequestLayout接口,这两个接口的调用是递归式的,最终又会调用到ViewRootinvalidateChildrequestLayout接口,ViewRoot又是什么?我们都知道View其实是一个个树状的结构,你可以认为ViewRoot就是这些树状结构的根节点。重新回来看一下这两个接口的实现如下:

public void invalidateChild(View child, Rect dirty) {
    checkThread();
    if (DEBUG_DRAW) Log.v(TAG, "Invalidate child: " + dirty);
    if (mCurScrollY != 0 || mTranslator != null) {
        mTempRect.set(dirty);
        dirty = mTempRect;
        if (mCurScrollY != 0) {
            dirty.offset(0, -mCurScrollY);
        }
        if (mTranslator != null) {
            mTranslator.translateRectInAppWindowToScreen(dirty);
        }
        if (mAttachInfo.mScalingRequired) {
            dirty.inset(-1, -1);
        }
    }
    mDirty.union(dirty);
    if (!mWillDrawSoon) {
        scheduleTraversals();
    }
}


public void requestLayout() {
    checkThread();
    mLayoutRequested = true;
    scheduleTraversals();
}

值得注意的是,这两个接口中都调用到了checkThread这个接口,那么这个接口又是检查什么呢:

void checkThread() {
    if (mThread != Thread.currentThread()) {
        throw new CalledFromWrongThreadException(
                
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值