2012-03-04 179 views
0

我有一個典型WindowLeaked例外WindowLeaked從對話框

03-03 21:03:26.441:ERROR /窗口管理(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泄漏窗口 [email protected] 最初是在這裏添加的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: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 錯誤/ WindowManager(631):在 android.os.Looper.loop 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 錯誤/ WindowManager(631):在 錯誤/ WindowManager(631)錯誤/ WindowManager(631):0335 21:03:26.441: :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 /窗口管理器(631):在 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

那是什麼'progressDialog.dismiss( )'在那裏?我認爲我們需要更多代碼才能查明問題。 – dmon 2012-03-04 03:53:09

+0

@dmon它只是擺脫加載progressDialog。即使我完全刪除了activity中的progressDialog,我仍然得到錯誤,所以這不是問題 – Cameron 2012-03-05 23:36:52

+0

@dmon我添加了更多的代碼 – Cameron 2012-03-08 00:24:14

回答

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不爲空...

你能檢查你的錯誤處理程序是否被調用?也許嘗試不打電話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

+0

我試過這個,並修改它的版本,但我仍然收到錯誤 – Cameron 2012-03-10 22:42:06

+0

是你的播放器活動代碼執行時仍然在運行? – Matthieu 2012-03-11 19:36:47

+0

我認爲這可能是問題,所以我在完成之前嘗試調用'arg0.release()'和'mPlayer.release()',但都導致應用程序崩潰 – Cameron 2012-03-12 12:14:08

0

的錯誤監聽器事件可能不會回來給你UI(looper)線程。您需要將事件發佈到處理程序(在UI線程中註冊),讓處理程序顯示Toast並關閉進度對話框。

+0

如創建一個onClick監聽器,其中包含來自錯誤偵聽器的所有代碼,但未註冊它對任何事物。發生錯誤時,只需調用onClick監聽器?對不起,我不是一個專家,當涉及到Android ... – Cameron 2012-03-04 02:48:05

+0

我試過這個,但問題仍然存在 – Cameron 2012-03-08 00:10:39