Rahul Kumar
Rahul Kumar

Reputation: 2344

Not able to play many audio files in Android using MediaPlayer objects

I have a large list view. Each list view item has a play button (image). On clicking that play button it will play some small audio file.

I created an Adapter to load elements in list view and implemented onClick listener on play.

When I launch the application, it is loading list properly but there is some problem in audio. When I play few (like 10-12) items many times (like 100) it will not create any problem everything will run smoothly.

But if I play more items like 30-40 items in the list. It stops loading audio files for later items. For items, it was working it will continue to work, for new items it don't work.

enter image description here

    public class WordListAdapter extends BaseAdapter{
    private ArrayList<Word> wordArrayList;
    private Activity activity;
    private static LayoutInflater inflater=null;
    MediaPlayer mp;

    public WordListAdapter(Activity activity, ArrayList<Word> wordArrayList) {
        this.activity = activity;
        this.wordArrayList = wordArrayList;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return wordArrayList.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, final View convertView, final ViewGroup parent) {
        View view = convertView;
        if(convertView == null) {
            view = inflater.inflate(R.layout.item_word, null);
        }

        TextView word1 = (TextView) view.findViewById(R.id.word1);
        TextView word2 = (TextView) view.findViewById(R.id.word2);
        ImageView imageWord = (ImageView) view.findViewById(R.id.imageWord);
        ImageView playWord = (ImageView) view.findViewById(R.id.playWord);

        word1.setText(wordArrayList.get(position).lang1);
        word2.setText(wordArrayList.get(position).lang2);

        if(wordArrayList.get(position).pic == 0) {
            imageWord.setVisibility(GONE);
        }
        else {
            imageWord.setImageResource(wordArrayList.get(position).pic);
        }

        playWord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mp = MediaPlayer.create(activity, wordArrayList.get(position).audio);
                mp.start();
            }
        });

        return view;
    }
}

I guess the problem is because I have created too many Media Player objects.

How to fix it?

Upvotes: 4

Views: 138

Answers (2)

Andrei
Andrei

Reputation: 51

MediaPlayer uses system codecs, which will eventually come to an end if you do not release the previously created MediaPlayers. So try to call mp.release(). For example, try this (just i am not sure it will work - release itself):

playWord.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mp = MediaPlayer.create(activity, wordArrayList.get(position).audio);
            mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
               @Override
               public void onCompletion(MediaPlayer mediaPlayer) {
                   mediaPlayer.release();
               }
            });
            mp.start();
       }
});

Upvotes: 1

Mithun Sarker
Mithun Sarker

Reputation: 4023

I once faced the similar problem, what did I do is to use service for playing media file . I am sharing what I did. Create a service like following

public class PlayMusicService extends Service
        implements MediaPlayer.OnCompletionListener,  MediaPlayer.OnErrorListener {

    private int audioResource;
    public static MediaPlayer player;


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        audioResource = intent.getIntExtra("musicResource",0);
        player = MediaPlayer.create(this, audioResource);
        player.setLooping(false);
        player.setVolume(100, 100);
        player.setOnCompletionListener(this);
        player.setOnErrorListener(this);
        player.start();
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        player.stop();
        player.release();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        this.onDestroy();
    }

    @Override
    public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
        return false;
    }
}

Then call this service like following

        playWord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               Intent serviceIntent = new Intent(getActivity(),PlayMusicService.class);
               serviceIntent.putExtra("musicResource", wordArrayList.get(position).audio);
            }
        });

Let me know of if it works for you . One thing to be remembered here you might need to use a local broadcast manager for changing the view from your service.

Upvotes: 1

Related Questions