java.lang.IllegalStateException

报错:java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child’s parent first.

导读:最近给我的项目添加一个新功能,引用前面的写过的一个输入框,该输入框是一个继承于fragment的子类;我将其使用在了一个布局文件中,该布局文件又是一个fragment类的布局文件;而这个类又是我写的一个有三个fragment成员的viewpager中的一个。所以在循环点击多次该fragment对应的Tab的时候会报该错。说的可能有点模糊,但由于知识有限也不知道怎么描述了。大体上的框架就是:一个ViewPager里面包含3个fragment:fragment1,fragment2,fragment3;而fragment3使用的布局文件layout里面引用了一个fragment的类。

布局代码:

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/bj_qt"
    android:orientation="horizontal">

    <LinearLayout
        android:id="@+id/tpm11"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <ListView
            android:id="@+id/circlegroupchatlist"
            android:layout_width="fill_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#ededec"
            android:cacheColorHint="#00000000"
            android:divider="#d2d2d6"
            android:dividerHeight="0.5dip" />

        <LinearLayout
            android:id="@+id/chattx"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:orientation="horizontal"
            android:visibility="gone" >

            <ImageView
                android:id="@+id/dfxx"
                android:layout_width="0dip"
                android:layout_height="150dip"
                android:layout_gravity="right"
                android:layout_marginLeft="10dip"
                android:layout_marginRight="10dip"
                android:layout_weight="1" />

            <ImageView
                android:id="@+id/zjxx"
                android:layout_width="0dip"
                android:layout_height="150dip"
                android:layout_gravity="left"
                android:layout_marginLeft="10dip"
                android:layout_marginRight="10dip"
                android:layout_weight="1" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/dhbj_ty"
            android:gravity="center"
            android:orientation="vertical" >

            <fragment
                class="com.gymhd.hyd.ui.activity.frament.**InputFrament2**"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:id="@+id/inpute"
                tools:layout="@layout/fragment_inpute2" />


        </LinearLayout>

    </LinearLayout>

    <RelativeLayout 
        android:id="@+id/num_qd"
        android:layout_width="60dp"
        android:layout_height="40dp"
        android:layout_alignParentRight="true"
        android:visibility="visible"
        android:background="@drawable/bg_qd"
        >
       <TextView 
           android:id="@+id/qd_unread_num"
           android:layout_width="25dp"
           android:layout_height="25dp"
           android:background="@drawable/shap_yx"
           android:text="15"
           android:textColor="@color/white"
           android:gravity="center"
           /> 
          <TextView 
           android:layout_width="25dp"
           android:layout_height="25dp"
           android:background="@drawable/ql_qd"
           android:layout_centerInParent="true"
           /> 
    </RelativeLayout>
</RelativeLayout>

代码注释:以上代码中的InputFrament2就是那个fragment输入框的引用了,也是问题所在。

出错分析与讲解
我在刚遇到该问题的时候就试着现将其注释掉果然就没问题了,故确定问题出在该处,然后接着上网、问大神查找解决方法;最后总结了出错原因,其实从报错的字面意思大致也能知道一点的那就是父类被onDestroy了,子类的view还没被回收。这是怎么回事呢?按理来说父类都被干掉了,子类不应该还在的啊。通过一些博文的了解解释是“这是由于某位写代码的员工抱怨没发奖金,稍稍偷懒了,少写了一部分代码,没有考虑到Fragment再去嵌套Fragment的情况。”所以造成了如今苦逼的我们。

解决方法
既然知道了问题所在解决应该就简单了,可我不知道是我遇到的问题特殊还是怎么回事,我尝试了很多种网上的方法都没搞定,不过伤天不负有心人啊,最后我终于搞定了。我也总结到了一个经验,那就是有时候不能照搬别人的方法,多动脑筋思考才能找到最适合自己的解决方案。好了不长篇大论了,还是说说我怎么解决的吧!
1、发现问题:
通过打印日志发现viewpager里面的fragment只能保留两个第三个总会被ondestroy,在快用到他的时候再oncreate。但是在销毁fragment3的时候没有对其子类的InputFrament2进行处理。
2、解决问题:

package com.gymhd.hyd.ui.activity.frament;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.RelativeLayout;

import com.gymhd.hyd.common.HiydApplication;
import com.gymhd.hyd.entity.CircleThreeMemberPartVar;
import com.gymhd.hyd.entity.GroupChatRecordPartVar;
import com.gymhd.hyd.ui.activity.Sing_for_Group;
import com.gymhd.hyd.ui.adapter.CircleGroupChatAdp;
import com.gymhd.hyd.ui.slefdefined.TastView;
import com.gymhd.hyd.util.LogUtil;

import wen.ddsjw.mhd.R;


public class CircleGroupChatFrament extends Fragment {
    private View                circleGroupView;
    private ListView            listView;
    private RelativeLayout      relativeLayout;
    private CircleGroupChatAdp  circleGroupChatAdp;
    private CircleThreeMemberPartVar circleThreeMemberPartVar;

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        LogUtil.logw(getClass().getName(), "i am circlegroup oncreateview");

        String gno_now = HiydApplication.circlePropertyPartVar
                .getCirclePropertyDataSource().get("gno");
        circleThreeMemberPartVar = HiydApplication.circleThreeMemberPartVar;
        circleThreeMemberPartVar.setCircleGroupChatFrament(this);

        ***if (circleGroupView == null) {
            circleGroupView = inflater.inflate(R.layout.act_circlegroupchat, null);
        }***
        circleGroupChatAdp = new CircleGroupChatAdp(getActivity(), gno_now);
        listView = (ListView) circleGroupView.findViewById(R.id.circlegroupchatlist);
        relativeLayout = (RelativeLayout) circleGroupView.findViewById(R.id.num_qd);

        operationView();

        return circleGroupView;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LogUtil.logw(getClass().getName(), "i am circlegroup oncreate");
        if(savedInstanceState==null)
            return;
    }
    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        TastView.hide(true);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LogUtil.logw(getClass().getName(), "i am circlegroup ondestroy");
        ***ViewGroup parent = (ViewGroup) circleGroupView.getParent();
        if (parent != null) {
            parent.removeAllViews();
        }***
    }

    public void updateUI() {
        if (null != circleGroupChatAdp) {
            new Handler(Looper.getMainLooper()).postAtFrontOfQueue(new Runnable() {

                        @Override
                        public void run() {
                            circleGroupChatAdp
                                    .setData(circleThreeMemberPartVar.getdataCircleGroup());
                            circleGroupChatAdp.notifyDataSetChanged();
                            selectLastOne();
                        }
                    });

        }
    }

    /**
     * 让列表显示最后一行
     */
    private void selectLastOne() {
        listView.setSelection(circleGroupChatAdp.getCount());
    }

    private void operationView() {
        listView.setAdapter(circleGroupChatAdp);
        GroupChatRecordPartVar.circleGroupChatFrament = this;

        relativeLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(getActivity(),
                        Sing_for_Group.class);
                startActivity(i);
            }
        });
    }
}

代码注释:重点就是在onCreateView中的circleGroupView 空判断,还有onDestroy中的销毁操作

参考链接:
http://www.tuicool.com/articles/2eM32a
http://blog.csdn.net/hack8/article/details/24680995

java.lang.illegalstateexceptionJava编程语言中的一个异常类(exception class),通常是由于程序处于非法状态(illegal state)时抛出的异常。这个异常类通常会在以下情况下抛出: 1. 当试图访问已经关闭的流(stream)时,会抛出java.lang.illegalstateexception的异常。例如,你尝试访问一个已经关闭的文件流,这时就会出现这个异常。 2. 当尝试调用已经被删除的对象(object)时,也会抛出这个异常。这通常是因为在程序运行过程中,某个对象被删除了,但是其他部分的代码对该对象仍然有引用,这时就会抛出这个异常。 3. Java中的状态转换错误也会导致java.lang.illegalstateexception异常的产生。例如,当某个类要求程序必须处于某种状态才能执行某个操作时,如果程序当前不处于这种状态,就会抛出这个异常。 4. 如果使用某个已经被终止的线程,也会引发java.lang.illegalstateexception异常。这通常是由于程序员在代码中没有正确处理线程的生命周期,导致线程被意外地终止。 总之,java.lang.illegalstateexception异常通常意味着程序在某个方面处于非法状态,需要对程序进行适当的修复或处理来解决这个问题。因此,当你遇到这个异常时,应该首先检查程序的状态,特别是那些对对象、线程、文件流等进行操作的代码。如果无法确定问题所在,可以查看异常的堆栈跟踪(stack trace)以了解更多信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值