wil*_*rmo 5 android memory-leaks android-mediaplayer leakcanary
我有一个媒体播放器作为成员变量的活动。
我的媒体播放器是这样初始化的:
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(MyActivity.this, URL);
mMediaPlayer.prepareAsync();
//i set a on Prepared Listener to start playing on Prepared
Run Code Online (Sandbox Code Playgroud)
一切正常,然后我覆盖我的活动 onStop 方法以释放媒体播放器。
if(mMediaPlayer!=null){
if(mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
}
mMediaPlayer.release();
mMediaPlayer=null;
}
Run Code Online (Sandbox Code Playgroud)
但是在活动停止后,我从 LeakCanary 收到了内存泄漏报告。
报告是这样的:
MyApp.Instance->
MyApp.mLoadedApk->
LoadedApk.mReceivers->
ArrayMap.mArray->
arrayObject[].[3]->
ArrayMap.mArray->
arrayObject[][0]->
MediaPlayer.mProxyReceiver->
MediaPlayer.mProxyContext->
leaks MyActivity instance.
MyApp.Instance->
MyApp.mLoadedApk->
LoadedApk.mReceivers->
ArrayMap.mArray->
arrayObject[].[3]->
ArrayMap.mArray->
arrayObject[][0]->
MediaPlayer.mProxyReceiver->
MediaPlayer.mProxyContext->
leaks MyActivity instance.
Run Code Online (Sandbox Code Playgroud)
是的,我有一个扩展 Application 的 MyApp 类,并且我在静态字段中持有对 MyApp 实例的引用,但我从未在我的活动中使用该引用,我该如何解决这个泄漏?
[编辑]
这是我的活动代码:
public class PlayActivity extends ActionBarActivity {
private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
protected void onStop() {
super.onStop();
if(mediaPlayer!=null){
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
}
mediaPlayer.release();
mediaPlayer=null;
}
}
public void playIt(View view){
if(mediaPlayer==null){
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
if(!mediaPlayer.isPlaying()){
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(PlayActivity.this, Uri.parse("http://www.noiseaddicts.com/samples_1w72b820/142.mp3"));
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中,我发现这种情况发生在 HTTP 流传输期间。
当我检查目标上MediaPlayer的源代码(在我的例子是API19)时,确实有一个StreamProxy实例被设置和分配,但没有在方法中释放release,而只是在reset方法中释放。
这对我有用:
if (mediaPlayer != null) {
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3453 次 |
| 最近记录: |