Android MediaPlayer AudioStream AudioFlinger server died!, Fatal signal 11Android

Forum für diejenigen, die für Android programmieren
Anonymous
 Android MediaPlayer AudioStream AudioFlinger server died!, Fatal signal 11

Post by Anonymous »

Ich habe zwei Fragmente (links und rechts) und erhalte im linken Fragment eine Liste von Radiostreams. Durch Klicken auf einen dieser Streams sollte das rechte Fragment den Namen des Streams ändern und mit der Wiedergabe des Streams mit der angegebenen URI beginnen.

2 Probleme:
  • Einige der Radiostreams sind nicht auf dem neuesten Stand, daher funktionieren viele nicht mehr. Das Problem ist, dass meine App dadurch einen Forceclose durchführt! Ich habe eine Fehlerbehandlung durchgeführt, aber nach dem Aufruf eines solchen Streams erhalte ich Folgendes:

03-20 14:23:28.192: A/libc(1021): Fatal signal 11 (SIGSEGV) at
0x00000000 (code=1)

20.03. 14:23:28.192: W/AudioSystem(1021): AudioFlinger-Server gestorben!

20.03. 14:23:28.192: W/IMediaDeathNotifier(1021): Medienserver gestorben

20.03 14:23:28.192: E/MediaPlayer(1021): Fehler (100, 0)

03-20 14:23:28.192: I/ServiceManager(1021): Warten auf Dienst
media.audio_flinger...

03-20 14:23:28.752: I/dalvikvm(1021): threadid=3: Reagiert auf Signal 3

03-20 14:23:28.782: I/dalvikvm(1021): Schrieb Stack-Traces in
'/data/anr/traces.txt'

03-20 14:23:29.192: I/ServiceManager(1021): Warten auf Service
media.audio_flinger...


Ich weiß nicht warum. Gibt es eine andere Möglichkeit zur Fehlerbehandlung? Oder gibt es eine Möglichkeit, alle Streams vor dem Aufruf von mediaPlayer.setDataSource(uri) zu überprüfen, um die Vorbereitung defekter Uris zu vermeiden? (siehe meinen Code am Ende)
  • Ich steuere das linke ListFragment mit einer Fernbedienung. Wenn ich versuche, sehr schnell von einem Kanal zum anderen zu wechseln, ist alles sehr verzögert. Es scheint, dass die Wiederherstellung des Mediaplayers sehr lange dauert. Wenn ich keine erneute Instanziierung durchführe, erhalte ich einen Laufzeitfehler, wenn ich mediaPlayer.setDataSource(..) erneut aufrufe. Gibt es eine Möglichkeit, .setDataSource zweimal für ein MediaPlayer-Objekt aufzurufen?
Hier ist mein Code:
Meine MediaPlayer-Wrapper-Klasse:

Code: Select all

package net.smart4life.tvplay.model;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.util.Log;

/**
* A wrapper class for {@link android.media.MediaPlayer}.
*
* Encapsulates an instance of MediaPlayer, and makes a record of its internal
* state accessible via a {@link MediaPlayerWrapper#getState()} accessor.
*/
public class MediaPlayerStateWrapper {

private static String tag = "MediaPlayerWrapper";
private MediaPlayer mPlayer;
private State currentState;
private MediaPlayerStateWrapper mWrapper;

public MediaPlayerStateWrapper() {
mWrapper = this;
mPlayer = new MediaPlayer();
currentState = State.IDLE;
mPlayer.setOnPreparedListener(mOnPreparedListener);
mPlayer.setOnCompletionListener(mOnCompletionListener);
mPlayer.setOnBufferingUpdateListener(mOnBufferingUpdateListener);
mPlayer.setOnErrorListener(mOnErrorListener);
mPlayer.setOnInfoListener(mOnInfoListener);
}

/* METHOD WRAPPING FOR STATE CHANGES */
public static enum State {
IDLE, ERROR, INITIALIZED, PREPARING, PREPARED, STARTED, STOPPED, PLAYBACK_COMPLETE, PAUSED;
}

public void setDataSource(String path) {
if (currentState == State.IDLE) {
try {
mPlayer.setDataSource(path);
currentState = State.INITIALIZED;
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else
throw new RuntimeException();
}

public void prepareAsync() {
Log.d(tag, "prepareAsync()");
if (EnumSet.of(State.INITIALIZED, State.STOPPED).contains(currentState)) {
mPlayer.prepareAsync();
currentState = State.PREPARING;
} else
throw new RuntimeException();
}

public boolean isPlaying() {
Log.d(tag, "isPlaying()");
if (currentState != State.ERROR) {
return mPlayer.isPlaying();
} else
throw new RuntimeException();
}

public void seekTo(int msec) {
Log.d(tag, "seekTo()");
if (EnumSet.of(State.PREPARED, State.STARTED, State.PAUSED,
State.PLAYBACK_COMPLETE).contains(currentState)) {
mPlayer.seekTo(msec);
} else
throw new RuntimeException();
}

public void pause() {
Log.d(tag, "pause()");
if (EnumSet.of(State.STARTED, State.PAUSED).contains(currentState)) {
mPlayer.pause();
currentState = State.PAUSED;
} else
throw new RuntimeException();
}

public void start() {
Log.d(tag, "start()");
if (EnumSet.of(State.PREPARED, State.STARTED, State.PAUSED,
State.PLAYBACK_COMPLETE).contains(currentState)) {
mPlayer.start();
currentState = State.STARTED;
} else
throw new RuntimeException();
}

public void stop() {
Log.d(tag, "stop()");
if (EnumSet.of(State.PREPARED, State.STARTED, State.STOPPED,
State.PAUSED, State.PLAYBACK_COMPLETE).contains(currentState)) {
mPlayer.stop();
currentState = State.STOPPED;
} else
throw new RuntimeException();
}

public void reset() {
Log.d(tag,  "reset()");
mPlayer.reset();
currentState = State.IDLE;
}

/**
* @return The current state of the mediaplayer state machine.
*/
public State getState() {
Log.d(tag, "getState()");
return currentState;
}

public void release() {
Log.d(tag, "release()");
mPlayer.release();
}

/* INTERNAL LISTENERS */
private OnPreparedListener mOnPreparedListener = new OnPreparedListener() {

@Override
public void onPrepared(MediaPlayer mp) {
Log.d(tag, "on prepared");
currentState = State.PREPARED;
mWrapper.onPrepared(mp);
mPlayer.start();
currentState = State.STARTED;
}
};
private OnCompletionListener mOnCompletionListener = new OnCompletionListener() {

@Override
public void onCompletion(MediaPlayer mp) {
Log.d(tag, "on completion");
currentState = State.PLAYBACK_COMPLETE;
mWrapper.onCompletion(mp);
}
};
private OnBufferingUpdateListener mOnBufferingUpdateListener = new OnBufferingUpdateListener() {

@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.d(tag, "on buffering update");
mWrapper.onBufferingUpdate(mp, percent);
}
};
private OnErrorListener mOnErrorListener = new OnErrorListener() {

@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.d(tag, "on error");
currentState = State.ERROR;
mWrapper.onError(mp, what, extra);
return false;
}
};
private OnInfoListener mOnInfoListener = new OnInfoListener() {

@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
Log.d(tag, "on info");
mWrapper.onInfo(mp, what, extra);
return false;
}
};

/* EXTERNAL STUBS TO OVERRIDE */
public void onPrepared(MediaPlayer mp) {
}

public void onCompletion(MediaPlayer mp) {
}

public void onBufferingUpdate(MediaPlayer mp, int percent) {
}

boolean onError(MediaPlayer mp, int what, int extra) {
// Error Handling of type: "MEdiaPlayer error(100,0)
mp.stop();
mp.release();
return false;
}

public boolean onInfo(MediaPlayer mp, int what, int extra) {
return false;
}

/* OTHER STUFF */
public int getCurrentPosition() {
if (currentState != State.ERROR) {
return mPlayer.getCurrentPosition();
} else {
return 0;
}
}

public int getDuration() {
// Prepared, Started, Paused, Stopped, PlaybackCompleted
if (EnumSet.of(State.PREPARED, State.STARTED, State.PAUSED,
State.STOPPED, State.PLAYBACK_COMPLETE).contains(currentState)) {
return mPlayer.getDuration();
} else {
return 100;
}
}
}
Hier ist mein TestFragment (rechtes Fragment). Hinweis: Das linke Fragment ruft jedes Mal, wenn auf ein Listenelement geklickt wurde, die Methode „newChannel(radioChannel)“ von TestFragment auf.

Code: Select all

package net.smart4life.tvplay.fragment;

import java.io.IOException;

import net.smart4life.tvplay.R;
import net.smart4life.tvplay.model.MediaPlayerStateWrapper;
import net.smart4life.tvplay.model.RadioChannel;
import android.app.Fragment;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

public class TestFragment extends Fragment {

private RadioChannel radioCh;
private TextView tv_RadioCh;
private MediaPlayerStateWrapper mediaWrapper;
private View view;

// firstcall
public TestFragment(RadioChannel radioChannel) {
this.radioCh = radioChannel;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);

setRetainInstance(true);

tv_RadioCh = (TextView) view.findViewById(R.id.radioText);

mediaWrapper = new MediaPlayerStateWrapper();

newChannel(radioCh);
}

public void newChannel (RadioChannel radioChannel) {
this.radioCh = radioChannel;
Log.e("RadioChannel", radioCh.getName());
tv_RadioCh.setText(radioCh.getName());

if(mediaWrapper.isPlaying()) {
mediaWrapper.stop();
mediaWrapper.reset();
} else if(mediaWrapper.getState() == MediaPlayerStateWrapper.State.PREPARING) {
mediaWrapper.release();
mediaWrapper = new MediaPlayerStateWrapper();
}
mediaWrapper.setDataSource(radioCh.getUrl().toString());
mediaWrapper.prepareAsync();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

view = inflater.inflate(R.layout.fragment_radio_player, container,
false);

return view;
}

@Override
public void onDetach() {
super.onDetach();

mediaWrapper.release();
}

}
Profis, könnten Sie mir bitte bei einer oder beiden Fragen helfen?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post