我有一个典型的WindowLeaked异常
03-03 21:03:26.441:ERROR / WindowManager(631):活动 com.myapp.Player泄漏了窗口 com.android.internal.policy.impl.PhoneWindow$DecorView@45136c38那个 最初被添加到这里03-03 21:03:26.441: ERROR / WindowManager(631):android.view.WindowLeaked:Activity com.myapp.Player泄漏了窗口 com.android.internal.policy.impl.PhoneWindow$DecorView@45136c38那个 最初被添加到这里03-03 21:03:26.441: 错误/ WindowManager(631):at android.view.ViewRoot。(ViewRoot.java:247)03-03 21:03:26.441: 错误/ 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: 错误/ 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: 错误/ 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: 错误/ 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(原生方法)
到目前为止,我所阅读的答案似乎都无法解决。这是代码:
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()之后放置toast以查看它是否可行。我完全没有想法,所以任何帮助都会很棒。
更新:以下是更多代码
@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;
}
};
当设备无法播放的视频类型时出现错误
答案 0 :(得分:2)
也许你可以尝试通过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中)。
似乎错误来自AlertDialog.Builder ......但是基于你的代码,它甚至不应该到达那里,因为当mOnErrorListener不为null时错误应该被处理得更高......
您可以检查是否正在调用您的错误处理程序吗?也许尝试不在那里调用finish()?
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;
然后“默认”错误处理程序将不会尝试构建此AlertDialog
答案 1 :(得分:0)
错误监听器事件可能不会在UI(looper)线程上回复给您。您需要将事件发布到处理程序(在UI线程上注册),让处理程序显示Toast并关闭进度对话框。