App crashes onPlaying audio in Adapter of listview second time

岁酱吖の 提交于 2019-12-02 13:06:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!