对话框泄漏的窗口 [英] WindowLeaked from Dialog

查看:78
本文介绍了对话框泄漏的窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个典型的WindowLeaked异常

I'm having a typical WindowLeaked exception

03-03 21:03:26.441:错误/WindowManager(631):活动 com.myapp.Player窗口泄漏 com.android.internal.policy.impl.PhoneWindow$DecorView@45136c38那 最初是在这里添加03-03 21:03:26.441 错误/WindowManager(631):android.view.WindowLeaked:活动 com.myapp.Player窗口泄漏 com.android.internal.policy.impl.PhoneWindow$DecorView@45136c38那 最初是在这里添加03-03 21:03:26.441 错误/WindowManager(631):在 android.view.ViewRoot.(ViewRoot.java:247)03-03 21:03:26.441: 错误/WindowManager(631):在 android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148) 03-03 21:03:26.441:错误/WindowManager(631):在 android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 03-03 21:03:26.441:错误/WindowManager(631):在 android.view.Window $ LocalWindowManager.addView(Window.java:424)03-03 21:03:26.441:错误/WindowManager(631):在 android.app.Dialog.show(Dialog.java:241)03-03 21:03:26.441: 错误/WindowManager(631):在 android.app.AlertDialog $ Builder.show(AlertDialog.java:802)03-03 21:03:26.441:错误/WindowManager(631):在 android.widget.VideoView $ 4.onError(VideoView.java:387)03-03 21:03:26.441:错误/WindowManager(631):在 android.media.MediaPlayer $ EventHandler.handleMessage(MediaPlayer.java:1264) 03-03 21:03:26.441:错误/WindowManager(631):在 android.os.Handler.dispatchMessage(Handler.java:99)03-03 21:03:26.441:错误/WindowManager(631):在 android.os.Looper.loop(Looper.java:123)03-03 21:03:26.441: 错误/WindowManager(631):在 android.app.ActivityThread.main(ActivityThread.java:4627)03-03 21:03:26.441:错误/WindowManager(631):在 java.lang.reflect.Method.invokeNative(本机方法)03-03 21:03:26.441:错误/WindowManager(631):在 java.lang.reflect.Method.invoke(Method.java:521)03-03 21:03:26.441: 错误/WindowManager(631):在 com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:868) 03-03 21:03:26.441:错误/WindowManager(631):在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)03-03 21:03:26.441:错误/WindowManager(631):在 dalvik.system.NativeStart.main(本机方法)

03-03 21:03:26.441: ERROR/WindowManager(631): Activity com.myapp.Player has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@45136c38 that was originally added here 03-03 21:03:26.441: ERROR/WindowManager(631): android.view.WindowLeaked: Activity com.myapp.Player has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@45136c38 that was originally added here 03-03 21:03:26.441: ERROR/WindowManager(631): at android.view.ViewRoot.(ViewRoot.java:247) 03-03 21:03:26.441: ERROR/WindowManager(631): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148) 03-03 21:03:26.441: ERROR/WindowManager(631): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 03-03 21:03:26.441: ERROR/WindowManager(631): at android.view.Window$LocalWindowManager.addView(Window.java:424) 03-03 21:03:26.441: ERROR/WindowManager(631): at android.app.Dialog.show(Dialog.java:241) 03-03 21:03:26.441: ERROR/WindowManager(631): at android.app.AlertDialog$Builder.show(AlertDialog.java:802) 03-03 21:03:26.441: ERROR/WindowManager(631): at android.widget.VideoView$4.onError(VideoView.java:387) 03-03 21:03:26.441: ERROR/WindowManager(631): at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:1264) 03-03 21:03:26.441: ERROR/WindowManager(631): at android.os.Handler.dispatchMessage(Handler.java:99) 03-03 21:03:26.441: ERROR/WindowManager(631): at android.os.Looper.loop(Looper.java:123) 03-03 21:03:26.441: ERROR/WindowManager(631): at android.app.ActivityThread.main(ActivityThread.java:4627) 03-03 21:03:26.441: ERROR/WindowManager(631): at java.lang.reflect.Method.invokeNative(Native Method) 03-03 21:03:26.441: ERROR/WindowManager(631): at java.lang.reflect.Method.invoke(Method.java:521) 03-03 21:03:26.441: ERROR/WindowManager(631): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 03-03 21:03:26.441: ERROR/WindowManager(631): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 03-03 21:03:26.441: ERROR/WindowManager(631): at dalvik.system.NativeStart.main(Native Method)

到目前为止,我没有读过的答案似乎都可以解决.这是代码:

None of the answers I've read so far seem to solve it. Here is the code:

mVideoView.setOnErrorListener(new OnErrorListener() {
    @Override
    public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
        Toast.makeText(Player.this, "Sorry, unable to play this video", Toast.LENGTH_LONG).show();
        progressDialog.dismiss();
        if (mToken != null) {
            MusicUtils.unbindFromService(mToken);
        }
        finish();
        return false;
    }
});

我唯一留下的猜​​测是吐司继续进行着这项活动,但是我正在阅读的所有内容似乎都表明吐司并不重要.我什至尝试使用getBaseContext(),然后尝试将吐司放在finish()之后,看它是否可以工作.我全都没主意,所以任何帮助都会很棒.

The only guess I was left with was that the toast was holding on to the activity, but everything I'm reading seems to say the toast doesn't matter. I even tried using getBaseContext(), and then tried putting the toast after finish() to see if it would work. I'm all out of ideas so any help would be awesome.

更新:这是更多的代码

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        extras = getIntent().getExtras();
        media_url = extras.getString("media_url");
        setContentView(R.layout.video_player);
        //Start progress dialog so user knows something is going on
        progressDialog = ProgressDialog.show(this, "", "Loading...", true);
        mVideoView = (VideoView) findViewById(R.id.surface_view);

        runOnUiThread(new Runnable(){
            public void run() {
                playVideo();
            }
        });
    }

    private void playVideo() {
        try {
            if (media_url == null || media_url.length() == 0) {
                progressDialog.dismiss();
                Toast.makeText(VideoPlayer.this, "File URL/media_url is empty",
                        Toast.LENGTH_LONG).show();

            } else {
                // If the path has not changed, just start the media player
                if (media_url.equals(current) && mVideoView != null) {
                    mVideoView.start();
                    mVideoView.requestFocus();
                    return;
                }
                current = media_url;
                mVideoView.setVideoURI(Uri.parse(media_url));
                ctlr=new MediaController(VideoPlayer.this);
                ctlr.setMediaPlayer(mVideoView);
                mVideoView.setMediaController(ctlr);
                mVideoView.requestFocus();
                mVideoView.setOnPreparedListener(new OnPreparedListener() {

                    public void onPrepared(MediaPlayer arg0) {
                        progressDialog.dismiss();
                        mVideoView.start();
                    }
                });
                mVideoView.setOnErrorListener(new OnErrorListener() {

                    @Override
                    public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
                        Toast.makeText(VideoPlayer.this, "Sorry, unable to play this video",
                                Toast.LENGTH_LONG).show();
                        progressDialog.dismiss();
                        if (mToken != null) {
                            MusicUtils.unbindFromService(mToken);
                        }
                        finish();
                        return false;
                    }
                });


            }
        } catch (Exception e) {
            Log.e(TAG, "error: " + e.getMessage(), e);
            if (mVideoView != null) {
                mVideoView.stopPlayback();
            }
            finish();
        }
    }

    private void startPlayback() {

        if(mService == null)
            return;
        Intent intent = getIntent();
        String filename = "";
        Uri uri = intent.getData();
        if (uri != null && uri.toString().length() > 0) {
            String scheme = uri.getScheme();
            if ("file".equals(scheme)) {
                filename = uri.getPath();
            } else {
                filename = uri.toString();
            }
            try {
                mService.stop();
                mService.openFileAsync(filename);
                mService.play();
                setIntent(new Intent());
            } catch (Exception ex) {
                Log.e(tag, "couldn't start playback: " + ex);
            }
        }
    }

    private ServiceConnection osc = new ServiceConnection() {
        public void onServiceConnected(ComponentName classname, IBinder obj) {
            mService = IMediaPlaybackService.Stub.asInterface(obj);
            startPlayback();
        }
        public void onServiceDisconnected(ComponentName classname) {
            mService = null;
        }
     };

当设备无法播放的视频类型时发生错误

Error is occurring when it is a video type the device can't play

推荐答案

也许您可以尝试通过

Maybe you could try to show your Toast through runOnUiThread ?

类似的东西:

    @Override
    public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
       Player.this.runOnUiThread(new Runnable() {
           void run() {
               Toast.makeText(Player.this, "Sorry, unable to play this video", Toast.LENGTH_LONG).show();
               progressDialog.dismiss();
               if (mToken != null) {
                    MusicUtils.unbindFromService(mToken);
                }
                finish();
           }
        );
        return false;
    }

编辑:

更多...下面是VideoView的代码(在Froyo中).

Here is more...below is the code (in Froyo) for the VideoView.

似乎错误来自AlertDialog.Builder ...,但根据您的代码,它甚至不应该到达那里,因为当mOnErrorListener不为null时,错误应得到更高的处理...

Seems like the error comes from the AlertDialog.Builder... but based on your code, it should not even get there since the error should be handled higher when mOnErrorListener is not null...

您可以检查是否调用了错误处理程序吗?也许尝试不在那里调用finish()?

Can you check whether your error handler is being called ? Maybe try to not call finish() there ?

 private MediaPlayer.OnErrorListener mErrorListener =
        new MediaPlayer.OnErrorListener() {
        public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
            Log.d(TAG, "Error: " + framework_err + "," + impl_err);
            mCurrentState = STATE_ERROR;
            mTargetState = STATE_ERROR;
            if (mMediaController != null) {
                mMediaController.hide();
            }

            /* If an error handler has been supplied, use it and finish. */
            if (mOnErrorListener != null) {
                if (mOnErrorListener.onError(mMediaPlayer, framework_err, impl_err)) {
                    return true;
                }
            }

            /* Otherwise, pop up an error dialog so the user knows that
             * something bad has happened. Only try and pop up the dialog
             * if we're attached to a window. When we're going away and no
             * longer have a window, don't bother showing the user an error.
             */
            if (getWindowToken() != null) {
                Resources r = mContext.getResources();
                int messageId;

                if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
                    messageId = com.android.internal.R.string.VideoView_error_text_invalid_progressive_playback;
                } else {
                    messageId = com.android.internal.R.string.VideoView_error_text_unknown;
                }

                new AlertDialog.Builder(mContext)
                        .setTitle(com.android.internal.R.string.VideoView_error_title)
                        .setMessage(messageId)
                        .setPositiveButton(com.android.internal.R.string.VideoView_error_button,
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                        /* If we get here, there is no onError listener, so
                                         * at least inform them that the video is over.
                                         */
                                        if (mOnCompletionListener != null) {
                                            mOnCompletionListener.onCompletion(mMediaPlayer);
                                        }
                                    }
                                })
                        .setCancelable(false)
                        .show();
            }
            return true;
        }
    };

更多

将onError处理程序更改为return true;

Change the onError handler to return true;

然后,默认"错误处理程序将不会尝试构建此AlertDialog

Then the "default" error handler will not try to build this AlertDialog

这篇关于对话框泄漏的窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆