Android异常:RelativeLayout$LayoutParams cannot be cast to android.widget.LinearLayout$LayoutParams

项目开发中碰到一个异常比较奇怪,因为这个异常一旦出现会然你很头疼,因为从奔溃日志中你基本找不到有用的信息,比如这个:

java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams cannot be cast to android.widget.LinearLayout$LayoutParams
                                                                    at android.widget.LinearLayout.measureVertical(LinearLayout.java:720)
                                                                    at android.widget.LinearLayout.onMeasure(LinearLayout.java:629)
                                                                    at android.view.View.measure(View.java:20171)
                                                                    at android.widget.ListView.setupChild(ListView.java:2031)
                                                                    at android.widget.ListView.makeAndAddView(ListView.java:1950)
                                                                    at android.widget.ListView.fillSpecific(ListView.java:1379)
                                                                    at android.widget.ListView.layoutChildren(ListView.java:1746)
                                                                    at android.widget.AbsListView.onLayout(AbsListView.java:2723)
                                                                    at android.view.View.layout(View.java:17945)
                                                                    at android.view.ViewGroup.layout(ViewGroup.java:5812)
                                                                    at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:630)
                                                                    at android.view.View.layout(View.java:17945)
                                                                    at android.view.ViewGroup.layout(ViewGroup.java:5812)
                                                                    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1742)
                                                                    at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1731)
                                                                    at android.widget.LinearLayout.onLayout(LinearLayout.java:1496)
                                                                    at android.view.View.layout(View.java:17945)
                                                                    at android.view.ViewGroup.layout(ViewGroup.java:5812)
                                                                    at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1080)
                                                                    at android.view.View.layout(View.java:17945)
                                                                    at android.view.ViewGroup.layout(ViewGroup.java:5812)
                                                                    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
                                                                    at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
                                                                    at android.view.View.layout(View.java:17945)
                                                                    at android.view.ViewGroup.layout(ViewGroup.java:5812)
                                                                    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1742)
                                                                    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
                                                                    at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
                                                                    at android.view.View.layout(View.java:17945)
                                                                    at android.view.ViewGroup.layout(ViewGroup.java:5812)
                                                                    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
                                                                    at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
                                                                    at android.view.View.layout(View.java:17945)
                                                                    at android.view.ViewGroup.layout(ViewGroup.java:5812)
                                                                    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1742)
                                                                    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
                                                                    at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
                                                                    at android.view.View.layout(View.java:17945)
                                                                    at android.view.ViewGroup.layout(ViewGroup.java:5812)
                                                                    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
                                                                    at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
                                                                    at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:3178)
                                                                    at android.view.View.layout(View.java:17945)
                                                                    at android.view.ViewGroup.layout(ViewGroup.java:5812)
                                                                    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2716)
                                                                    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2417)
                                                                    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1487)
                                                                    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7450)
                                                                    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:920)
                                                                    at android.view.Choreographer.doCallbacks(Choreographer.java:695)
                                                                    at android.view.Choreographer.doFrame(Choreographer.java:631)
                                                                    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:906)
                                                                    at android.os.Handler.handleCallback(Handler.java:739)
                                                                    at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                    at android.os.Looper.loop(Looper.java:158)
                                                                    at android.app.ActivityThread.main(ActivityThread.java:7225)
                                                                    at java.lang.reflect.Method.invoke(Native Method)
                                                                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

从log中看这个异常,信息中没有报类似的cause by信息,也就找不到异常出现在项目中的哪行代码。这个时候你可能会去点源码中的listView的代码,因为log中出现ndroid.widget.ListView类似信息,一番折腾下来然而并没有什么软用,怎么办呢?

这个时候我就去分析对比异常出现前后的代码,异常出现前后改动的布局文件,当然也会分析下ListView附近的改动代码。如上的这个异常是这么出现的:

我有一个View一开始是放在RelativeLayout里,此时运行Ok,然后我把这个View放到了一个LinearLayout里并且单独提出来作为一个layout,之后我又调用了ListView的addHeader方法把这个layout  Add进去了,因此出现了上面的错误,

一开始分析ListView也没分析出啥原因,后面看到View一开始是RelativeLayout的子View,后面View作为了LinearLayout的子View就出现了上面的异常;到这里还没看懂异常的原因,然后分析代码,结果看到这么一段

 RelativeLayout.LayoutParams gallery_lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height);
 slider.setLayoutParams(gallery_lp);
View指的就是slider,顿时焕然大悟。然后我就把如上代码改成如下,异常就没了。

LinearLayout.LayoutParams gallery_lp = new LinearLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height);
slider.setLayoutParams(gallery_lp);
原因就是因为slider之后作为了LinearLayout的子View,它的Layoutparams就因该是它的父View的LayoutParams,所以就应该把slider的LayoutParams从RelativeLayout$LayoutParams改成LinearLayout$LayoutParams。

写这个的原因就是告诉自己,遇到这样的错误,就因该从这几个步骤解决问题:

  • 基本的定位异常出现的代码行数,分析...
  • 代码回退,然后对比分析代码找原因
  • 分析异常前后改动的Layout文件
  • 分析改动的View在代码中的调用
也希望这些总结能给大家带来帮助,谢谢!



你可能感兴趣的:(android难点记录)