View标签与view标签引发的bug思考
来源:互联网 发布:360排名优化 编辑:程序博客网 时间:2024/06/05 22:52
题引:前些天想用View标签写个下划线,结果把View写成view了,出现了一个奇葩的bug。
- bug堆栈
- bug分析
- 源码分析
一、bug堆栈
03-09 15:35:28.654 29199-29199/com.jiudaifu.yangsheng E/AndroidRuntime: FATAL EXCEPTION: main Process: com.jiudaifu.yangsheng, PID: 29199 **java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference** at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:734) at android.view.LayoutInflater.rInflate(LayoutInflater.java:825) at android.view.LayoutInflater.rInflate(LayoutInflater.java:828) at android.view.LayoutInflater.inflate(LayoutInflater.java:523) at android.view.LayoutInflater.inflate(LayoutInflater.java:425) at android.view.LayoutInflater.inflate(LayoutInflater.java:368) at com.jiudaifu.yangsheng.adapter.CaseListAdapter.getView(CaseListAdapter.java:51) at android.widget.AbsListView.obtainView(AbsListView.java:2369) at android.widget.ListView.measureHeightOfChildren(ListView.java:1274) at android.widget.ListView.onMeasure(ListView.java:1186) at android.view.View.measure(View.java:17628) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5548) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1467) at android.widget.LinearLayout.measureVertical(LinearLayout.java:747) at android.widget.LinearLayout.onMeasure(LinearLayout.java:638) at android.view.View.measure(View.java:17628) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5548) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at android.view.View.measure(View.java:17628) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5548) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1467) at android.widget.LinearLayout.measureVertical(LinearLayout.java:747) at android.widget.LinearLayout.onMeasure(LinearLayout.java:638) at android.view.View.measure(View.java:17628) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5548) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1467) at android.widget.LinearLayout.measureVertical(LinearLayout.java:747) at android.widget.LinearLayout.onMeasure(LinearLayout.java:638) at android.view.View.measure(View.java:17628) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5548) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at android.view.View.measure(View.java:17628) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5548) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1467) at android.widget.LinearLayout.measureVertical(LinearLayout.java:747) at android.widget.LinearLayout.onMeasure(LinearLayout.java:638) at android.view.View.measure(View.java:17628) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5548) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2639) at android.view.View.measure(View.java:17628) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2081) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1217) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1423) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1105) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6204) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:799) at android.view.Choreographer.doCallbacks(Choreographer.java:612) at android.view.Choreographer.doFrame(Choreographer.java:581) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:785) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5669) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)03-09 15:35:28.964 29199-29199/com.jiudaifu.yangsheng I/Process: Sending signal. PID: 29199 SIG: 9
二、bug分析
1、bug:在一个空指针上调用equals()方法。
2、事实上,我没调用过equals()这个方法。
3、跟进Android源码,发现是Android源码调用equals()方法报空指针异常。
涉及的Android源码如下:
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs, boolean ignoreThemeAttr) { if (name.equals("view")) { name = attrs.getAttributeValue(null, "class"); } // Apply a theme wrapper, if allowed and one is specified. if (!ignoreThemeAttr) { final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME); final int themeResId = ta.getResourceId(0, 0); if (themeResId != 0) { context = new ContextThemeWrapper(context, themeResId); } ta.recycle(); } if (name.equals(TAG_1995)) { // Let's party like it's 1995! return new BlinkLayout(context, attrs); } try { View view; if (mFactory2 != null) { view = mFactory2.onCreateView(parent, name, context, attrs); } else if (mFactory != null) { view = mFactory.onCreateView(name, context, attrs); } else { view = null; } if (view == null && mPrivateFactory != null) { view = mPrivateFactory.onCreateView(parent, name, context, attrs); } if (view == null) { final Object lastContext = mConstructorArgs[0]; mConstructorArgs[0] = context; try { if (-1 == name.indexOf('.')) { view = onCreateView(parent, name, attrs); } else { view = createView(name, null, attrs); } } finally { mConstructorArgs[0] = lastContext; } } return view; } catch (InflateException e) { throw e; } catch (ClassNotFoundException e) { final InflateException ie = new InflateException(attrs.getPositionDescription() + ": Error inflating class " + name); ie.initCause(e); throw ie; } catch (Exception e) { final InflateException ie = new InflateException(attrs.getPositionDescription() + ": Error inflating class " + name); ie.initCause(e); throw ie; } }
三、Android源码分析
1、Android源码通过判断标签名是View还是view来做不同逻辑处理。
2、如果是view的话就会去获取class属性的值,但是我在xml中并没有设置class属性的值,因此获取到的将会是空指针,进而执行到equals()方法时就会报空指针。
3、另外,view也是可以用作xml标签的,不过是用于在xml中引用内部类的View
参考:http://blog.csdn.net/gorgle/article/details/51428515
0 0
- View标签与view标签引发的bug思考
- 自定义view--打折标签view
- 表单提交后分页页面标签POST实现 —— 一个小小的bug引发的思考
- 自定义标签View
- html的em标签引发的一系列思考
- 自定义view---带标签的CalendarView
- 自定义View-自动换行的标签控件
- 一个BUG引发的思考
- android自定义view 流式标签View
- MVC view 显示html 标签
- 让view标签显示波浪
- <f:view>标签是社么含义
- 实现View 上添加标签
- 自定义view之热门标签
- Android三角标签View:TriangleLabelView
- Android三角标签View:TriangleLabelView
- 使用merge标签自定义View
- 实现View上添加标签
- Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2)
- 简单的输入
- git提交到远程仓库出现问题
- sublime中书写vue 语法高亮插件安装
- RPM软件包管理命令简介
- View标签与view标签引发的bug思考
- 数据查询
- 23种设计模式模式详解 Java 行为型模式(三)
- ubuntu16.04配置shadowshocks和chrome
- Chinese Girls' Amusement (大数除法,大数减法)
- 2.Unity3D商业游戏源码研究-变身吧主公-SceneMgr
- 5069. 蛋糕
- NET 获取类内成员的名称,以字符串形式显示
- 一个按时提醒休息的简单C语言程序