Reputation: 2344
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.
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
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
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