通过实例验证播放本地音乐MediaPlayer的reset函数并不会阻塞主线程

来源:互联网 发布:mac延长待机时间 编辑:程序博客网 时间:2024/06/09 23:38

如题,通过下面的一个例子,频繁点击播放下一首歌,验证MediaPlayer的reset函数是否会发生阻塞。

验证数据如下:在从20:26:04.673到20:26:36.168的32秒时间内,点击170次Next播放下一首歌曲,都成功,没有发生阻塞主线程导致ANR的问题。

由于本例播放的都是本地歌曲 ,所以没有发生阻塞的情况。如果是播放在线歌曲,需要与网络交换,频繁执行播放动作,可能会发生ANR;播放网络歌曲需要使用异步的prepareAsync函数,而不能使用同步的prepare,以免发生阻塞。

(1)第一次播放的log如下:

06-24 20:26:04.673 26426 26426 D MainActivity: -------------------------------
06-24 20:26:04.678 26426 26426 D MainActivity: play next music
06-24 20:26:04.678 26426 26426 D MainActivity: before reset
06-24 20:26:04.683 26426 26426 D MainActivity: after reset
06-24 20:26:04.683 26426 26426 D MainActivity: before setDataSource:/mnt/sdcard/Music/白安/麦田捕手-白安.mp3
06-24 20:26:04.763 26426 26426 D MainActivity: after setDataSource to prepare
06-24 20:26:04.768 26426 26426 D MainActivity: onPrepared
06-24 20:26:04.898 26426 26426 D MainActivity: -------------------------------


(2)最后6次播放的log如下:

06-24 20:26:35.013 26426 26426 D MainActivity: -------------------------------
06-24 20:26:35.013 26426 26426 D MainActivity: play next music
06-24 20:26:35.013 26426 26426 D MainActivity: before reset
06-24 20:26:35.018 26426 26426 D MainActivity: after reset
06-24 20:26:35.018 26426 26426 D MainActivity: before setDataSource:/mnt/sdcard/Music/Download/余生一起过-刘德华.aac
06-24 20:26:35.068 26426 26426 D MainActivity: after setDataSource to prepare
06-24 20:26:35.073 26426 26426 D MainActivity: onPrepared
06-24 20:26:35.213 26426 26426 D MainActivity: -------------------------------
06-24 20:26:35.213 26426 26426 D MainActivity: play next music
06-24 20:26:35.213 26426 26426 D MainActivity: before reset
06-24 20:26:35.218 26426 26426 D MainActivity: after reset
06-24 20:26:35.218 26426 26426 D MainActivity: before setDataSource:/mnt/sdcard/Music/白安/麦田捕手-白安.mp3
06-24 20:26:35.298 26426 26426 D MainActivity: after setDataSource to prepare
06-24 20:26:35.308 26426 26426 D MainActivity: onPrepared
06-24 20:26:35.403 26426 26426 D MainActivity: -------------------------------
06-24 20:26:35.403 26426 26426 D MainActivity: play next music
06-24 20:26:35.403 26426 26426 D MainActivity: before reset
06-24 20:26:35.403 26426 26426 D MainActivity: after reset
06-24 20:26:35.403 26426 26426 D MainActivity: before setDataSource:/mnt/sdcard/Music/Download/幸福就是-刘若英.mp3
06-24 20:26:35.463 26426 26426 D MainActivity: after setDataSource to prepare
06-24 20:26:35.463 26426 26426 D MainActivity: onPrepared
06-24 20:26:35.593 26426 26426 D MainActivity: -------------------------------
06-24 20:26:35.593 26426 26426 D MainActivity: play next music
06-24 20:26:35.593 26426 26426 D MainActivity: before reset
06-24 20:26:35.598 26426 26426 D MainActivity: after reset
06-24 20:26:35.598 26426 26426 D MainActivity: before setDataSource:/mnt/sdcard/Music/Download/余生一起过-刘德华.aac
06-24 20:26:35.678 26426 26426 D MainActivity: after setDataSource to prepare
06-24 20:26:35.683 26426 26426 D MainActivity: onPrepared
06-24 20:26:35.983 26426 26426 D MainActivity: -------------------------------
06-24 20:26:35.983 26426 26426 D MainActivity: play next music
06-24 20:26:35.983 26426 26426 D MainActivity: before reset
06-24 20:26:35.983 26426 26426 D MainActivity: after reset
06-24 20:26:35.983 26426 26426 D MainActivity: before setDataSource:/mnt/sdcard/Music/白安/麦田捕手-白安.mp3
06-24 20:26:36.068 26426 26426 D MainActivity: after setDataSource to prepare
06-24 20:26:36.073 26426 26426 D MainActivity: onPrepared
06-24 20:26:36.168 26426 26426 D MainActivity: -------------------------------
06-24 20:26:36.168 26426 26426 D MainActivity: play next music
06-24 20:26:36.168 26426 26426 D MainActivity: before reset
06-24 20:26:36.173 26426 26426 D MainActivity: after reset
06-24 20:26:36.173 26426 26426 D MainActivity: before setDataSource:/mnt/sdcard/Music/Download/幸福就是-刘若英.mp3
06-24 20:26:36.238 26426 26426 D MainActivity: after setDataSource to prepare
06-24 20:26:36.243 26426 26426 D MainActivity: onPrepared


(3)执行reset前后的log如下,reset在极短的时间内就会执行完毕,一般在10毫秒以内。

3:06-24 20:26:04.678 26426 26426 D MainActivity: before reset
4:06-24 20:26:04.683 26426 26426 D MainActivity: after reset
10:06-24 20:26:04.898 26426 26426 D MainActivity: before reset
11:06-24 20:26:04.898 26426 26426 D MainActivity: after reset
17:06-24 20:26:05.063 26426 26426 D MainActivity: before reset
18:06-24 20:26:05.068 26426 26426 D MainActivity: after reset
24:06-24 20:26:05.243 26426 26426 D MainActivity: before reset
25:06-24 20:26:05.243 26426 26426 D MainActivity: after reset
31:06-24 20:26:05.578 26426 26426 D MainActivity: before reset
32:06-24 20:26:05.583 26426 26426 D MainActivity: after reset
38:06-24 20:26:05.758 26426 26426 D MainActivity: before reset
39:06-24 20:26:05.763 26426 26426 D MainActivity: after reset
45:06-24 20:26:05.918 26426 26426 D MainActivity: before reset
46:06-24 20:26:05.918 26426 26426 D MainActivity: after reset
52:06-24 20:26:06.098 26426 26426 D MainActivity: before reset
53:06-24 20:26:06.098 26426 26426 D MainActivity: after reset
......

1144:06-24 20:26:34.838 26426 26426 D MainActivity: before reset
1145:06-24 20:26:34.838 26426 26426 D MainActivity: after reset
1151:06-24 20:26:35.013 26426 26426 D MainActivity: before reset
1152:06-24 20:26:35.018 26426 26426 D MainActivity: after reset
1158:06-24 20:26:35.213 26426 26426 D MainActivity: before reset
1159:06-24 20:26:35.218 26426 26426 D MainActivity: after reset
1165:06-24 20:26:35.403 26426 26426 D MainActivity: before reset
1166:06-24 20:26:35.403 26426 26426 D MainActivity: after reset
1172:06-24 20:26:35.593 26426 26426 D MainActivity: before reset
1173:06-24 20:26:35.598 26426 26426 D MainActivity: after reset
1179:06-24 20:26:35.983 26426 26426 D MainActivity: before reset
1180:06-24 20:26:35.983 26426 26426 D MainActivity: after reset
1186:06-24 20:26:36.168 26426 26426 D MainActivity: before reset
1187:06-24 20:26:36.173 26426 26426 D MainActivity: after reset


(4)验证代码如下:

public class MainActivity extends Activity implements View.OnClickListener{    private static final String TAG = "MainActivity";    private MediaPlayer mMediaPlayer = null;    private Button mBtnPlayStop;    private Button mBtnNext;        private boolean mIsPlayFlag = false;        private String mPathArray[] = new String[] {      "/mnt/sdcard/Music/白安/麦田捕手-白安.mp3",      "/mnt/sdcard/Music/Download/幸福就是-刘若英.mp3",      "/mnt/sdcard/Music/Download/余生一起过-刘德华.aac"    };    private int mIndex = 0;    public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                mBtnPlayStop = (Button)findViewById(R.id.btnPlayStop);        mBtnPlayStop.setOnClickListener(this);                mBtnNext = (Button)findViewById(R.id.btnNext);        mBtnNext.setOnClickListener(this);                setVolumeControlStream(AudioManager.STREAM_MUSIC);        mMediaPlayer = new MediaPlayer();        mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {            @Override            public void onPrepared(MediaPlayer arg0) {                Log.d(TAG, "onPrepared");                mMediaPlayer.start();            }                    });        mMediaPlayer.setOnCompletionListener(new OnCompletionListener()        {            @Override            public void onCompletion(MediaPlayer mp)            {                Log.d(TAG, "onCompletion");                next();            }        });        mMediaPlayer.setOnErrorListener(new OnErrorListener() {            @Override            public boolean onError(MediaPlayer mp, int what, int extra) {                Log.d(TAG, "onError what:" + what + ", extra:" + extra);                                return false;            }                    });    }    @Override    public void onClick(View v) {        switch (v.getId())          {          case R.id.btnPlayStop:            if (mIsPlayFlag) {                try {                    Log.d(TAG,"-------------------------------");                    Log.d(TAG, "play:" + mPathArray[mIndex]);                    Log.d(TAG, "before reset");                    mMediaPlayer.reset();                    Log.d(TAG, "after reset");                                        Log.d(TAG, "before setDataSource");                    mMediaPlayer.setDataSource(mPathArray[mIndex]);                    Log.d(TAG, "after setDataSource to prepare");                    mMediaPlayer.prepare();                } catch (Exception e) {                    e.printStackTrace();                }                mBtnPlayStop.setText("Stop");            } else {                Log.d(TAG,"-------------------------------");                Log.d(TAG, "stop" + mPathArray[mIndex]);                mMediaPlayer.stop();                mBtnPlayStop.setText("Play");            }                        mIsPlayFlag = !mIsPlayFlag;            break;        case R.id.btnNext:            Log.d(TAG,"-------------------------------");            Log.d(TAG, "play next music");            next();            break;        }      }     private void next() {        try {            Log.d(TAG, "before reset");            mMediaPlayer.reset();            Log.d(TAG, "after reset");                        if (mIndex < mPathArray.length - 1) {                mIndex++;            } else {                mIndex = 0;            }            Log.d(TAG, "before setDataSource:" + mPathArray[mIndex]);            mMediaPlayer.setDataSource(mPathArray[mIndex]);            Log.d(TAG, "after setDataSource to prepare");            mMediaPlayer.prepare();        } catch (Exception e) {            e.printStackTrace();        }    }}