android.view.ViewRootImpl.performTraversals

问题描述 投票:0回答:1

我有 MediaPlayer 活动。但很多用户不喜欢它,因为异常崩溃:

java.lang.NullPointerException
at android.os.Parcel.readException(Parcel.java:1333)
at android.os.Parcel.readException(Parcel.java:1281)
at android.view.IWindowSession$Stub$Proxy.relayout(IWindowSession.java:634)
at android.view.ViewRootImpl.relayoutWindow(ViewRootImpl.java:3751)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1321)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2587)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)

我无法在我的设备上重现此错误,但根据用户消息,我是一个糟糕的开发人员:))并且在视频播放开始几秒钟后出现此异常。有趣的是,即使在显示错误报告对话框后它仍然可以工作。

在android源代码中寻找原因,我发现它发生在使用iBinder进行事务之后。

mRemote.transact(Stub.TRANSACTION_relayout, _data, _reply, 0);
_reply.readException();

此代码使用在scheduleTraversals方法中调度的Runnable在ViewRootImpl的performTraversalsMethod中执行。而且很难获得它的执行上下文。 ScheduleTraversals 调用了很多方法(invalidate、handleScreenStateChange....)。

有什么想法吗?

android exception media-player surfaceview
1个回答
0
投票

发生这种情况是因为我在 Surface 上使用 WindowManager.LayoutParams.FLAG_SCALED。

但是正如我们从android源代码中看到的:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/com/android/server/ wm/WindowManagerService.java#2756

 if (attrs != null) {
            if (win.mAttrs.type != attrs.type) {
                throw new IllegalArgumentException(
                        "Window type can not be changed after the window is added.");
            }
            flagChanges = win.mAttrs.flags ^= attrs.flags;
            attrChanges = win.mAttrs.copyFrom(attrs);
        }

        //...


        final boolean scaledWindow =
            ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);

        if (scaledWindow) {
            // requested{Width|Height} Surface's physical size
            // attrs.{width|height} Size on screen
            win.mHScale = (attrs.width  != requestedWidth)  ?
                    (attrs.width  / (float)requestedWidth) : 1.0f;
            win.mVScale = (attrs.height != requestedHeight) ?
                    (attrs.height / (float)requestedHeight) : 1.0f;
        } else {
            win.mHScale = win.mVScale = 1;
        }

从第一个“if”我们看到 attr == null 是正常情况,但是在使用的情况下 scaledWindow 不检查此参数是否为 null。结果我们得到了 NullPointerException。

WindowManager.LayoutParams.FLAG_SCALED 在任何情况下都不应该使用。

© www.soinside.com 2019 - 2024. All rights reserved.