情景再现,从源码角度分析异常:The specified child already has a parent

转载请注明出处:http://blog.csdn.net/My_TrueLove/article/details/52230308
访问 ruicb.com,一键抵达我的博客!

0. 写在前面

开头先说几句题外话,与标题无关,想找答案的请跳到第二部分说正事

这两天看了两篇微信文章,分别是:

  1. 阿禅的 能说出来,才是你的知识
  2. 采访医生的 一个给程序看病的医生——徐宜生

这两个大人物不知道你们听说过没,反正我一直在关注他们的文章、书籍,当然咯,他们不认识我哈哈,不过这不是重点,重点是他们的文章、故事一直在激励着我。

上面两篇文章建议大家读一读,反正我读完后挺有感触的。先说说第一篇,与具体的技术无关,但告诉我们为什么要写博客,标题已经很明显了—能说出来,才是你的知识;再说说第二篇,医生在介绍进阶之路时,提到了一段话:

我认为要想真正达到进阶水平,初学者真的没有必要过度的掌握源码,先了解使用的方法,才能在后面进阶的时候游刃有余,基础不打好,一味的通过看源码,只会适得其反。

当然,当你基础达到一定程度,一定要去了解实现的原理,不然一样是之后原地踏步,而不能站着高级层面来看问题,就好像三体中的降维攻击——二向箔,再低的三维也比你最牛逼的二维叼!

这两篇文章对我还是有一定影响的,感言最后再说哈哈。也希望大家都能看一下,说不定一不小心就被感染了。废话就这些了,喝了这碗鸡汤,开始说正事!

1. 说正事

先来个异常作为见面礼:

Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

这个异常相信大家都有碰到过,大白话解释就是:一个子View已经有了父容器A,在将其添加到另一个父容器B之前,应该先调用父容器A的removeView()方法将该子View移除

1.1 再现情景

上面的异常意思懂了,但是为什么会有这个异常?下面我们来情景再现一下,直接上代码(代码是为再现情景,无实际意义):

情景再现

上述代码中,我们在第28行将button添加到了parent中,接着在32行又将button添加到linearLayout中,现在运行程序,惊了个呆,居然崩溃了(意料之中哈哈):

崩溃日志

崩溃日志中被圈出来的异常在开头就说了,同时日志将异常定位在程序第32行,也就是我们将button添加到linearLayout中的那一段。

1.2 分析源码

既然已经定位到那一行了,说明问题就出在addView(button)这个方法,不妨跟进去一探究竟!按住 Ctrl,点击方法名,一路追踪,路线图如下:

追踪路线

最终我们会进入addViewInner(xxx)方法中,看到了我们熟悉而又亲切的异常。该方法关键代码如下所示:

private void addViewInner(View child, int index, ViewGroup.LayoutParams params,
                          boolean preventRequestLayout) {
    //...
    if (child.getParent() != null) {
        throw new IllegalStateException("The specified child already has a parent. " +
                "You must call removeView() on the child's parent first.");
    }
    //...
}

在该方法中,会去判断待添加的 child,也就是我们的 button,其父容器是否不为空,如果是,那么就会抛出异常,提示我们:该child已经有了父容器,在添加之前你应该调用父容器的removeView()来移除该child

异常的出处和原因已经很明显了,同时,我们也知道了该如何解决这个问题。

1.3 解决问题

我的重点是如何通过源码分析问题,经过前面的分析,答案已经很明显了,我直接贴出我的解决方案供参考:

解决方案

2. 写在后面

文章阐述的异常其实很简单,是我上午在一个交流群看别人提的一个问题,于是我就查了一下,找到了答案,不过也仅仅是解决方法。如果放在以前就直接过去了,但因为看了医生的进阶路介绍,我干脆看了一下源码,一不小心就找到了问题所在;又因为阿禅的文章,于是就有了写篇文章的想法;再因为中午要下雨没去打球,所以抽空记录一下,来一发博客,哈哈。最后我的几点感想,与大家共勉:

  • 1.再小的问题,只要你不会,那就应该怀着前谦卑的态度去学习;
  • 2.知其然、知其所以然,才是正确的学习姿势。本文所说的问题很简单,上网搜索很多答案,但是如果我们只一味追求结果,不透过现象看本质,将一直徘徊在进阶的道路上。
  • 3.任何一个知识点,能说出来,才算是真正掌握—要坚持写博客。
  • 4.以上都是胡说的,每个人都应该有自己的观点哈 ^-^
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值