java.lang.IllegalArgumentException: No view found for id 0xad7b9d70 (unknown) for fragment, 爬坑
Posted 苦逼程序员_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java.lang.IllegalArgumentException: No view found for id 0xad7b9d70 (unknown) for fragment, 爬坑相关的知识,希望对你有一定的参考价值。
java.lang.IllegalArgumentException: No view found for id 0xad7b9d70 (unknown) for fragment, 爬出一个findViewById的坑
最近遇到一个比较奇怪且难定位的异常,是由新功能开发而导致的,在4.4模拟器上面初始化某个界面的时候会出现崩溃,崩溃信息如下。这个异常在真机以及5.0以上的模拟器上都不会出现。
java.lang.IllegalArgumentException: No view found for id 0xad7b9d70 (unknown) for fragment MyFragmentad792440 #0 id=0xad7b9d70 android:switcher:-1384407696:0
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1102)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1638)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:679)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1240)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1088)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
at android.view.View.measure(View.java:16497)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2291)
at android.view.View.measure(View.java:16497)
新功能的界面逻辑还算简单,一个viewPager + 两个fragment组成,异常报出来的信息是其中一个fragment找不到id为0xad7b9d70的view。堆栈信息全部都是源码内的,没有找到容易定位的关键信息。于是很自然的顺着异常报出来的信息进入MyFragment里面去看逻辑(掉进坑里),毫无疑问,找不到明显的问题。于是把MyFragment从viewPagerAdapter内移除,只加载一个Fragment,发现异常依旧,并且异常信息显示为另一个OtherFragment了。再把OtherFragment也移除掉,界面正常加载了,看来应该是Fragment加载进viewPager的过程种出现了问题。
在查看了自定义的CustomViewPager代码找不到问题后,跟着堆栈信息进入FragmentManager.moveToState()源码查看,发现了下面一段代码:
container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
if (container == null && !f.mRestored)
String resName;
try
resName = f.getResources().getResourceName(f.mContainerId);
catch (NotFoundException e)
resName = "unknown";
throwException(new IllegalArgumentException(
"No view found for id 0x"
+ Integer.toHexString(f.mContainerId) + " ("
+ resName
+ ") for fragment " + f));
异常确实是从这里抛出来的,原始是寻找container的时候找到了null,这里的f是参数传进来的Fragment,异常信息中报出的fragment就是当前参数f。通过调试,发现在真机和5.0以上的模拟器,mContainer.onFindViewById(f.mContainerId)都是正常获取到一个ViewGroup,唯独在4.4模拟器上面这句代码返回了null,看来问题就出来这里。继续调试进入源码findViewById(),代码如下:
@Nullable
public final View findViewById(@IdRes int id)
if (id < 0)
return null;
return findViewTraversal(id);
当调试到这个位置时,id<0这个条件成立了,直接返回了null,看来问题是出现在id这个位置。当Fragment加载到ViewPager上面时由于寻找容器的id小于0直接返回null,最终导致抛出异常崩溃。
查看跟id相关的的代码逻辑:
mViewPager = new CustomViewPager(getContext(), null);
mViewPager.setId(mViewPager.hashCode());
mViewPager.setAdapter(mPagerAdapter);
问题的关键点,应该是找到了,viewPager的id是通过setId方法设置进去的,并且没有遵循这个api的使用规范,设置 R.id.xxx 这种方式来设置id。
Object.hashCode()方法在不同的版本中会有不同的表现,目前仅在4.4的模拟器上发现它会返回负数。
修复方案:
1. mViewPager.setId(R.id.pager); (推荐)
2. mViewPager.setId(Math.abs(mViewPager.hashCode()));
以上是关于java.lang.IllegalArgumentException: No view found for id 0xad7b9d70 (unknown) for fragment, 爬坑的主要内容,如果未能解决你的问题,请参考以下文章