0

我有 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 ....)。

有任何想法吗?

4

1 回答 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。

于 2013-08-20T13:56:53.747 回答