小弟在做一个Activity,用来播放一个地址的影片,需要使用到SurfaceView,程序中使用线程进行播放。 需要在surfaceDestroyed的时候将MediaPlayer对象释放掉。但是有用线程需要用到MediaPlayer对象,因此在使用MediaPlayer对象的release方法时,程序会挂掉。请问各位大侠,有没有解决的方法。
先谢谢了
主要问题程序
============================================================================
  public void surfaceDestroyed(SurfaceHolder surfaceholder)
  {
    // TODO Auto-generated method stub  mMediaPlayer01.stop();
  mMediaPlayer01.release();
  }
=================================================================================以下为这个播放的Activity的程序
-----------------------------------------------------------------------------------------
package dlna.player.activities;import android.app.Activity;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;
import dlna.player.R;
import dlna.player.services.MediaPlayerService;public class VideoPlayerActivity extends Activity implements SurfaceHolder.Callback
{
  private TextView mTextView01;
  private static final String TAG = "HIPPO_MediaPlayer";
  
  private MediaPlayer mMediaPlayer01;
  
  private SurfaceView mSurfaceView01;
  
  private SurfaceHolder mSurfaceHolder01;
  
  MediaPlayerService MediaPlayerService01;
  
  DisplayMetrics dm = new DisplayMetrics();  
  private ImageButton mPlay;
  private ImageButton mback;
  private ImageButton mfront;
  
  private TextView begin;
  private TextView end;
  private SeekBar vedioseekbar;  
  private boolean bIsPaused = false;
  
  private boolean bIsReleased = false;
  
  private boolean bIsPlaying = false;
  
  private boolean IsFullScreen= false;
  
  private boolean IsFirstPlay= true;
  
  private String strVideoPath = null;
  private Uri strVideoPath1 = null;
  int Duration;
  Handler handler=new Handler();
  //Runnable startvedio=null;
  Runnable updatesb =null;
  
 
  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.video_player);
    
    
    mTextView01 = (TextView)findViewById(R.id.myTextView1);
    
    getWindow().setFormat(PixelFormat.UNKNOWN);
    
    mSurfaceView01 = (SurfaceView) findViewById(R.id.mSurfaceView1);
    
    getWindowManager().getDefaultDisplay().getMetrics(dm);
    LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) mSurfaceView01.getLayoutParams();
  linearParams.height=dm.heightPixels/2;
  linearParams.width=dm.widthPixels/2;
  mSurfaceView01.setLayoutParams(linearParams);
    
    
    mSurfaceHolder01 = mSurfaceView01.getHolder();
    mSurfaceHolder01.addCallback(this);
    
    //mSurfaceHolder01.setFixedSize(176,144);
    mSurfaceHolder01.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
     mPlay = (ImageButton) findViewById(R.id.play); 
    mback = (ImageButton) findViewById(R.id.back); 
    mfront = (ImageButton) findViewById(R.id.front); 
    vedioseekbar=(SeekBar)findViewById(R.id.SeekBar02);
    
    begin=(TextView)findViewById(R.id.begin);
    end=(TextView)findViewById(R.id.end);
   
    
    Intent intent = getIntent();
    strVideoPath = intent.getDataString();
    strVideoPath1 = intent.getData();
    
    mMediaPlayer01 =MediaPlayer.create(this,strVideoPath1);
    Duration=mMediaPlayer01.getDuration();
    vedioseekbar.setMax(Duration);
    
    vedioseekbar.setOnSeekBarChangeListener(seekbarlistener);
    
    begin.setText("00:00:00");
    end.setText(MediaPlayerService01.getTimeAsString(Duration));
    
    
    mPlay.setOnClickListener(new ImageButton.OnClickListener()
    { 
      public void onClick(View view)
      {
       if(IsFirstPlay)
       {
       if(!bIsPlaying){
       mTextView01.setText(R.string.download);
      handler.post(startvedio);
      //playVideo(strVideoPath);
    
     //handler.post(updatesb);
      }
       }
       else if(!IsFirstPlay){
       if(bIsPlaying==false){
       mMediaPlayer01.start();
       mTextView01.setText(R.string.str_play);
       mPlay.setImageResource(R.drawable.pause);
       bIsPlaying=true;
       }
       else if(bIsPlaying==true){
       mMediaPlayer01.pause();
       mTextView01.setText(R.string.str_pause);
       mPlay.setImageResource(R.drawable.play);
       bIsPlaying=false;
       }
       }
      }
      
      Runnable startvedio=new Runnable(){  
   @Override
   public void run() {
   // TODO Auto-generated method stub
   playVideo(strVideoPath);
  
   handler.post(updatesb);
   }
   
      };
      //This thread is used to update the seekbar.
      Runnable updatesb =new Runnable(){     
   @Override
   public void run() {
   // TODO Auto-generated method stub
   vedioseekbar.setProgress(mMediaPlayer01.getCurrentPosition());
   begin.setText(MediaPlayerService01.getTimeAsString(mMediaPlayer01.getCurrentPosition()));
   handler.postDelayed(updatesb, 1000);   }
   
      };
    });
    
  

解决方案 »

  1.   

        mback.setOnClickListener(new ImageButton.OnClickListener(){
         public void onClick(View view){
         if(mMediaPlayer01.getCurrentPosition()<10000)
         mMediaPlayer01.seekTo(0);
         else
        
         mMediaPlayer01.seekTo(mMediaPlayer01.getCurrentPosition()-10000);
         }
        });
        mfront.setOnClickListener(new ImageButton.OnClickListener(){
         public void onClick(View view){
         if((mMediaPlayer01.getCurrentPosition()+10000)>mMediaPlayer01.getDuration())
         mMediaPlayer01.seekTo(Duration);
         else
        
         mMediaPlayer01.seekTo(mMediaPlayer01.getCurrentPosition()+10000);
         }
        });
        mSurfaceView01.setOnClickListener(new SurfaceView.OnClickListener(){
         public void onClick(View view){
         if(mMediaPlayer01 != null){
         if(bIsReleased==false){
         if(IsFullScreen== false){
           mTextView01.setVisibility(mTextView01.INVISIBLE);
           mPlay.setVisibility(mPlay.INVISIBLE);
          
           mback.setVisibility(mback.INVISIBLE);
           mfront.setVisibility(mfront.INVISIBLE);
           begin.setVisibility(begin.INVISIBLE);
           end.setVisibility(end.INVISIBLE);
           vedioseekbar.setVisibility(vedioseekbar.INVISIBLE);
           LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) mSurfaceView01.getLayoutParams();
           linearParams.height=linearParams.FILL_PARENT;
           linearParams.width=linearParams.FILL_PARENT;
           mSurfaceView01.setLayoutParams(linearParams);
           IsFullScreen=true;
         }
         else if(IsFullScreen==true){
         mTextView01.setVisibility(mTextView01.VISIBLE);
         mPlay.setVisibility(mPlay.VISIBLE);
      
         mback.setVisibility(mback.VISIBLE);
         mfront.setVisibility(mfront.VISIBLE);
         begin.setVisibility(begin.VISIBLE);
         end.setVisibility(end.VISIBLE);
         vedioseekbar.setVisibility(vedioseekbar.VISIBLE);
           LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) mSurfaceView01.getLayoutParams();
           linearParams.height=dm.heightPixels/2;
           linearParams.width=dm.widthPixels/2;
           mSurfaceView01.setLayoutParams(linearParams);
           IsFullScreen=false;
         }
         mMediaPlayer01.start();
         mTextView01.setText(R.string.str_play);
         mPlay.setImageResource(R.drawable.pause);
         bIsPlaying=true;
         }
        
         }
         }
        });
      }
      
      
      private void playVideo(String strPath)
      { 
        mMediaPlayer01 = new MediaPlayer();
        mMediaPlayer01.setAudioStreamType(AudioManager.STREAM_MUSIC);
        
        mMediaPlayer01.setDisplay(mSurfaceHolder01);
        
        try
        { 
          mMediaPlayer01.setDataSource(strPath);
        }
        catch (Exception e)
        { 
          // TODO Auto-generated catch block
          mTextView01.setText("setDataSource Exceeption:"+e.toString());
          e.printStackTrace();
        }
        
        try
        { 
          mMediaPlayer01.prepare();
        }
        catch (Exception e)
        { 
          // TODO Auto-generated catch block
          mTextView01.setText("prepare Exceeption:"+e.toString());
          e.printStackTrace(); 
        }    mMediaPlayer01.start();
        mPlay.setImageResource(R.drawable.pause);
        bIsPlaying=true;
        IsFirstPlay=false;
        bIsReleased = false;
        
        mTextView01.setText(R.string.str_play);
        
        mMediaPlayer01.setOnCompletionListener
        (new MediaPlayer.OnCompletionListener()
        {
          @Override
          public void onCompletion(MediaPlayer arg0)
          {
            // TODO Auto-generated method stub
            mTextView01.setText(R.string.str_stop);
            bIsPlaying=false;
            mMediaPlayer01.seekTo(0);
            mPlay.setImageResource(R.drawable.play);
            //mMediaPlayer01.release();
           
            
          }
        });
      }
        public void mMakeTextToast(String str, boolean isLong)
      {
        if(isLong==true)
        {
          Toast.makeText(VideoPlayerActivity.this, str, Toast.LENGTH_LONG).show();
        }
        else
        {
          Toast.makeText(VideoPlayerActivity.this, str, Toast.LENGTH_SHORT).show();
        }
      }
      
      @Override
      public void surfaceChanged
      (SurfaceHolder surfaceholder, int format, int w, int h)
      {
        // TODO Auto-generated method stub
      }
      
      @Override
      public void surfaceCreated(SurfaceHolder surfaceholder)
      {
        // TODO Auto-generated method stub
      }
      
      @Override
      public void surfaceDestroyed(SurfaceHolder surfaceholder)
      {
        // TODO Auto-generated method stub  mMediaPlayer01.stop();
      mMediaPlayer01.release();
      }  private OnSeekBarChangeListener seekbarlistener=new OnSeekBarChangeListener(){
      
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
    boolean fromUser) {
    // TODO Auto-generated method stub
    } @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    // TODO Auto-generated method stub } @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    // TODO Auto-generated method stub
    mMediaPlayer01.seekTo(vedioseekbar.getProgress());
    }  };  
    }
      

  2.   

    释放时设置mMediaPlayer01 = null;
    在线程入口做判断 if(mMediaPlayer01 != null){...}
      

  3.   

    把和media有关的对象都定义在子线程类里面,主线程只负责UI,业务处理全部交给子线程做。通过handler来传递消息就行了,2个线程共享一个全局变量会出现问题的~~