android.text.Styled.drawDirectionalRun 中的 ClassCastException
我正在开发一个内部应用程序,该应用程序在时间轴上显示给定会议室的每日日程安排。每分钟,我都会访问网络服务并获取当天所有约会的信息,然后使用该数据创建自定义“时间线块”视图,以显示会议时间、客户等。然后删除所有约会从时间线中删除并使用新数据刷新它。我使用的自定义视图仅由一个 LinearLayout 和 3 个 TextView 组成。我想我应该注意到该活动的布局非常复杂,并且一些视图嵌套了大约 7 层深。
一切正常运行大约 2-3 天,然后应用程序就会崩溃。我设置为每 3 秒就会访问一次 Web 服务,现在大约每 2.5 小时就会发生一次崩溃。让我困惑的是,抛出的异常甚至没有指向我的代码中的任何内容。例外情况如下:
FATAL EXCEPTION: main
java.lang.ClassCastException: java.lang.String
at android.text.Styled.drawDirectionalRun(Styled.java:283)
at android.text.Styled.measureText(Styled.java:430)
at android.text.Layout.measureText(Layout.java:1655)
at android.text.Layout.getLineMax(Layout.java:689)
at android.text.Layout.getLineWidth(Layout.java:671)
at android.widget.TextView.desired(TextView.java:5037)
at android.widget.TextView.onMeasure(TextView.java:5083)
at android.view.View.measure(View.java:8171)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:578)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:362)
at android.view.View.measure(View.java:8171)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:578)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:362)
at android.view.View.measure(View.java:8171)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
at android.view.View.measure(View.java:8171)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
at android.view.View.measure(View.java:8171)
at android.view.ViewRoot.performTraversals(ViewRoot.java:801)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
如果我错误地转换了一个字符串(我很确定我没有),那么它是如何在本机代码中如此深入之前不会被捕获的?我在这里不知所措。这有可能是 Android 内部错误吗?
另一件可能有帮助的事情是:当这个应用程序崩溃时,它给出了相同的 ClassCastException,但在不同的位置。它发生在 BoringLayout.isBoring 函数中,这也是我的代码中从未触及的东西。
I am working on an internal app that displays the daily schedule for a given conference room on a timeline. Every minute, I hit a web service and get info back for all of the day's appointments, and I use that data to create custom "timeline block" views that show the time of the meeting, the client, etc. I then remove all appointments from the timeline and refresh it with the new data. The custom views I am using consist of nothing more than a LinearLayout with 3 TextViews inside it. I suppose I should note that the layout for the activity is pretty complex, and some views are nested about 7 layers deep.
Everything runs great for about 2-3 days, and then the app will crash. I made it so that it would hit the web service every 3 seconds, and now the crash will happen about every 2.5 hours. What gets me is that the exception that is thrown does not even point to anything in my code. Exception is below:
FATAL EXCEPTION: main
java.lang.ClassCastException: java.lang.String
at android.text.Styled.drawDirectionalRun(Styled.java:283)
at android.text.Styled.measureText(Styled.java:430)
at android.text.Layout.measureText(Layout.java:1655)
at android.text.Layout.getLineMax(Layout.java:689)
at android.text.Layout.getLineWidth(Layout.java:671)
at android.widget.TextView.desired(TextView.java:5037)
at android.widget.TextView.onMeasure(TextView.java:5083)
at android.view.View.measure(View.java:8171)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:578)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:362)
at android.view.View.measure(View.java:8171)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:578)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:362)
at android.view.View.measure(View.java:8171)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
at android.view.View.measure(View.java:8171)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
at android.view.View.measure(View.java:8171)
at android.view.ViewRoot.performTraversals(ViewRoot.java:801)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
If I am incorrectly casting a String (which I'm pretty sure I'm not), how is it that it wouldn't be caught until it's that deep in native code? I'm at a loss here. Is it possible this is an internal Android bug?
Another thing that might help: another time when this app crashed, it gave the same ClassCastException, but in a different spot. It happened in the BoringLayout.isBoring
function, which is also something that is never touched in my code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的 R.layout.stands_layout 必须是另一个中的很多 LinearLayouts
your R.layout.standings_layout must be a lot of LinearLayouts within the other
所以,事实证明,一直以来的问题都是 Android 在(不正确地)处置 TypeFace 对象时泄漏内存。我正在为每个文本标签创建一个新的 TypeFace,并且随着时间线的更新,每分钟时间线块都会被重新填充。
解决方案是创建可重用的 TypeFaces,以便全局可访问它们。我将它们放在 Application 类中,因为我的所有 Activity 都可以访问它。这样 Android 只需要处理几个对象而不是数百个。当然,它不能解决内部问题,但它是一种解决方法。该问题可能会在 ICS 中得到解决,但我不确定。
So, it turns out that the problem all along was that Android leaks memory when disposing (improperly) of TypeFace objects. I was creating a new TypeFace for every text label, and each minute the timeline blocks were being repopulated as the timeline was updated.
The solution is to create the TypeFaces that are reused so that they are globally accessible. I put them in the Application class since all my Activities can access it. That way Android only has to dispose of a few objects instead of hundreds. It doesn't fix the internal issue of course, but it is a workaround. The issue may be fixed as of ICS, but I'm not sure.