La Collecte des ordures causes : MediaPlayer finalisé sans être libérés
Après beaucoup de débogage, j'ai enfin trouvé ce qui est à l'origine de cette erreur! La Collecte Des Ordures!
J'ai de la lecture d'une vidéo en vue des médias et dans le fond je suis à la recherche de nouvelles vidéos à partir d'une API Rest.
Chaque maintenant et puis je voir de la collecte des Déchets en cours d'exécution:
02-22 13:14:57.969: D/dalvikvm(16888): GC_EXPLICIT freed 152K, 4% free 6746K/6979K, paused 2ms+2ms
Et le droit après:
02-22 13:14:57.969: W/MediaPlayer-JNI(16888): MediaPlayer finalized without being released
Donc je l'ai testé par le Système d'appel.gc() toutes les 5 secondes.
Dès que la première GC est appelé ça se passe!
02-22 13:19:47.813: D/dalvikvm(17060): GC_EXPLICIT freed 167K, 5% free 6745K/7047K, paused 2ms+2ms ---- I call GC
02-22 13:19:47.813: W/MediaPlayer-JNI(17060): MediaPlayer finalized without being released ---- VIDEO PLAY INTERRUPTED
Pourquoi cela se produit? Puis-je l'empêcher?
La lecture de la vidéo:
private void playMedia(int playListIndex) throws IOException {
File mediadir = getDir("tvr", Context.MODE_PRIVATE);
filelist = mediadir.listFiles();
Log.i("media player", "play media!");
String path = filelist[playListIndex].getAbsolutePath();
FileInputStream fileInputStream = new FileInputStream(path);
final Uri uri = Uri.parse(path);
String filename = filelist[playListIndex].getName();
if (filename.contains("image")) {
imageView = (ImageView)findViewById(R.id.imageView);
imageView.setVisibility(View.VISIBLE);
imageView.setImageURI(uri);
mHandler.postDelayed(new Runnable() {
public void run() {
imageView.setVisibility(View.GONE);
imageView.setImageURI(uri);
onCompletion(null);
}
}, 4000);
} else if (filename.contains("video")) {
MediaPlayer pl = new MediaPlayer();
pl.setOnCompletionListener(this);
pl.setDisplay(holder);
pl.setDataSource(fileInputStream.getFD());
pl.prepare();
pl.start();
}
}
Et quand c'est fait:
@Override
public void onCompletion(MediaPlayer mp) {
Log.i("media player", "play next please!");
if (mp != null) {
mp.release();
}
// play next video
currentMedia++;
if (currentMedia > playList.size() - 1) {
currentMedia = 0;
}
try {
playMedia(currentMedia);
} catch (IOException e) {
e.printStackTrace();
}
}
- Pourriez-Vous s'il vous plaît montrer un morceau de code où Vous avez mis en œuvre le mediaplayer?
- Salut, j'ai ajouté le code
Vous devez vous connecter pour publier un commentaire.
Je pense que c'est parce que vous créez le lecteur multimédia dans le champ d'application de la méthode, par conséquent, lorsque la méthode est terminée, elle est hors de portée. Cela signifie qu'il n'existe pas de références, donc c'est ok pour la collecte des ordures.
Cela signifie, il peut être libre avais par le GC avant elle a même appelé onCompletion, donc ne sera pas communiqué avant effacé. Au lieu de cela, vous avez besoin de stocker une référence à l'media player comme une variable de membre dans votre classe.
Media player cannot be referenced from a nonstatic context
MediaPlayer finalized without being released
Java GC seulement gère la mémoire. Alors, quand d'autres ressources sont utilisées (par exemple, des fichiers, sockets, etc), vous devez manuellement les gérer. Dans le cas de MediaPlayer, le la documentation mentionne que:
Donc, lorsque vous avez terminé avec un MediaPlayer exemple, vous devez assurez-vous d'appeler explicitement release() sur l'instance. Un bon endroit pour le faire, cela pourrait être dans un cycle de vie de la méthode de l'contenant de l'Activité, par exemple onDestroy(). Sinon, lorsque que MediaPlayer instance est finalement le garbage collector (à un certain arbitraire dans le temps après que vous avez cessé de référence), le finaliseur remarquerez que vous n'avez jamais appelé release() et de sortie de l'avertissement que vous voyez.