问题
My class consists of listview which contains list of tracks .Each list item consists of button Play and Pause.It should play track on clicking play and stop track on clicking pause.i am not using different buttons....i am using one button only which changes its text on clicking b/w play and pause and function accordingly. I am facing following issues- Clicking on play does play the track but when i stop the track by clicking pause and then try to play any track app crashes and shows following errors showing illegalstate exception
FATAL EXCEPTION: main
java.lang.IllegalStateException
at android.media.MediaPlayer._setDataSource(Native Method)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:966)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:926)
at xyz.SoundCloudAdapter$1.onClick(SoundCloudAdapter.java:86)
at android.view.View.performClick(View.java:4091)
at android.view.View$PerformClick.run(View.java:17072)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
at dalvik.system.NativeStart.main(Native Method)
SoundClassAdapter public class SoundCloudAdapter extends ArrayAdapter implements MediaPlayer.OnPreparedListener{ ArrayList soundcloudList; LayoutInflater vi; int Resource;
public static MediaPlayer mMediaPlayer;
public SoundCloudAdapter(Context context, int resource, ArrayList<SoundCloud> objects)
{
super(context, resource, objects);
vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Resource = resource;
soundcloudList = objects;
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnPreparedListener(this);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
final ViewHolder holder;
// convert view = design
View v = convertView;
if (v == null)
{
holder = new ViewHolder();
v = vi.inflate(Resource, null);
holder.textview = (TextView) v.findViewById(R.id.name);
holder.btn = (Button) v.findViewById(R.id.button);
holder.btn2 = (Button) v.findViewById(R.id.button2);
holder.textview2 = (TextView) v.findViewById(R.id.email);
v.setTag(holder);
}
else
{
holder = (ViewHolder) v.getTag();
}
holder.textview.setText(soundcloudList.get(position).getTitle());
holder.textview2.setText(soundcloudList.get(position).getId());
holder.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
notifyDataSetChanged();
if (holder.btn.getText().toString().equalsIgnoreCase("Play"))
{
holder.btn.setText("Pause");
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try
{
mMediaPlayer.setDataSource("http://api.soundcloud.com/tracks/"+soundcloudList.get(position).getId()+"/stream?client_id=xyz");
mMediaPlayer.prepareAsync();
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
notifyDataSetChanged();
}
else if (holder.btn.getText().toString().equalsIgnoreCase("Pause"))
{
holder.btn.setText("Play");
if(mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
mMediaPlayer.release();
notifyDataSetChanged();
}
}
});
return v;
}
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
static class ViewHolder
{
public TextView textview;
public Button btn;
public Button btn2;
public TextView textview2;
}
}
if i declare
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnPreparedListener(this); inside onClick()
track doesn't pause
回答1:
Try handle MediaPlayer state of each list item whenever it play and pause and also no need declare viewHolder object as final which may effect list item state.
public class SoundCloudAdapter extends BaseAdapter{
private MediaPlayer mMediaPlayer;
private Context context;
private ArrayList<SoundCloud> soundcloudList;
public SoundCloudAdapter(Context context, ArrayList<SoundCloud> soundcloudList){
this.context=context;
this.soundcloudList = soundcloudList;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getCount() {
return soundcloudList.size();
}
@Override
public Object getItem(int position) {
return soundcloudList.get(position);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null){
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.resource, null);
holder.textview = (TextView) convertView.findViewById(R.id.name);
holder.textview2 = (TextView) convertView.findViewById(R.id.email);
holder.btn = (Button) convertView.findViewById(R.id.button);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.textview.setText(soundcloudList.get(position).getTitle());
holder.textview2.setText(soundcloudList.get(position).getId());
holder.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
if(((Button)v).getText().toString().equals("Play")){
try{
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource("http://api.soundcloud.com/tracks/"+soundcloudList.get(position).getId()+"/stream?client_id=e13865f9debacb5f96375fdd96b7fa1b");
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
((Button)v).setText("Pause");
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mMediaPlayer.release();
mMediaPlayer = null;
((Button)v).setText("Play");
}
});
}catch (Exception e){
e.printStackTrace();
}
}else{
mMediaPlayer.release();
mMediaPlayer = null;
((Button)v).setText("Play");
}
notifyDataSetChanged();
}
});
return convertView;
}
static class ViewHolder
{
public TextView textview;
public TextView textview2;
public Button btn;
}
}
回答2:
Look at this code:
holder.btn.setText("Play");
if(mMediaPlayer.isPlaying()) {
mmMediaPlayer.stop();
}
mMediaPlayer.release();
notifyDataSetChanged();
If you want to resume playback you should not stop and release the MediaPlayer
, then you have to initialize it again. You should only call the pause()
method, which does just that, it stops the playback but it keeps the current position in the track and does not release the resources.
Also, remove the release()
call. Since you still want to use the same track again (when clicking play the next time).
EDIT: You should also check the code that runs on "Play", you dont need to set the data source every time you want to resume playback, just the first time.
来源:https://stackoverflow.com/questions/26798716/app-crashes-onplaying-audio-in-adapter-of-listview-second-time