主要error:JNI ERROR (app bug): attempt to use stale global reference 0x1d2004c2
原因:prepare()被声明native方法,准备播放的播放器同步需要设置datasource和display 之后才能唤醒prepare() ;
源码:
/**
* Prepares the player for playback, synchronously.
* <p/>
* After setting the datasource and the display surface, you need to either
* call prepare() or prepareAsync(). For files, it is OK to call prepare(),
* which blocks until MediaPlayer is ready for playback.
*
* @throws IllegalStateException if it is called in an invalid state
*/
public native void prepare() throws IOException, IllegalStateException;
MediaPlayerDemo_Audio.java修改后:
public class MediaPlayerDemo_Audio extends Activity implements
OnPreparedListener, SurfaceHolder.Callback {
......
private SurfaceHolder holder;
private SurfaceView mPreview;
......
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
if (!LibsChecker.checkVitamioLibs(this))
return;
setContentView(R.layout.audioplayer);
tx = (TextView) findViewById(R.id.tx);
mPreview = (SurfaceView) findViewById(R.id.surface);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setFormat(PixelFormat.RGBA_8888);
Bundle extras = getIntent().getExtras();
playAudio(extras.getInt(MEDIA));
}
private void playAudio(Integer media) {
try {
switch (media) {
case LOCAL_AUDIO:
path = "/storage/sdcard1/Movies/test.mp3";//这是我的本地路径,自行修改
if (path == "") {
// Tell the user to provide an audio file URL.
Toast.makeText(
MediaPlayerDemo_Audio.this,
"Please edit MediaPlayer_Audio Activity, "
+ "and set the path variable to your audio file path."
+ " Your audio file must be stored on sdcard.",
Toast.LENGTH_LONG).show();
return;
}
mMediaPlayer = new MediaPlayer(this);
mMediaPlayer.setDataSource(path);
// 使用prepare之前需要setting the datasource and the display
// surface否则调用了video会出现问题程序崩溃
mMediaPlayer.setDisplay(holder);
mMediaPlayer.prepare();
// 因为是异步的还没有prepare就调用start会报错,解决方法如下,使用:setOnPreparedListener
mMediaPlayer.setOnPreparedListener(this);
break;
tx.setText("Playing audio...");
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
}
......
@Override
public void onPrepared(MediaPlayer mp) {
mMediaPlayer.start();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
布局文件:audioplayer.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tx"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<io.vov.vitamio.widget.CenterLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<SurfaceView
android:id="@+id/surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" >
</SurfaceView>
</io.vov.vitamio.widget.CenterLayout>
</LinearLayout>
AndroidManifest.xml配置:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
欢迎关注微信公众号!你的每个赞和在看,都是对我的支持!👍