Mediaplayer will not release

kabalkabal AUMember
edited May 2015 in Xamarin.Android

Trying desperately to make a soundboard. Problem is that my mediaplayer is never ever being released no matter what I try, so after around 40 button/sound click/plays there are too many mediaplayers and the sound or app crashes. Please tell me how I can release mediaplayer everytime a sound stops playing because I can not get an answer from anywhere

using System;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Media;


namespace soundrelease

{
    [Activity (Label = "soundrelease", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        MediaPlayer mediaPlayer;

        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);

            // Set our view from the "main" layout resource
            SetContentView (Resource.Layout.Main);

            Button button1 = FindViewById<Button> (Resource.Id.button1);
            Button button2 = FindViewById<Button> (Resource.Id.button2);

            button1.Click += (object sender, EventArgs e) => {

                mediaPlayer = MediaPlayer.Create (this, Resource.Raw.sound01);
                mediaPlayer.Completion += (senderr, args) => {
                    if (!mediaPlayer.IsPlaying){
                        mediaPlayer.Release();
                        mediaPlayer = null;
                    }
                };  
                mediaPlayer.Start ();   
            };

            button2.Click += (object sender, EventArgs e) => {

                mediaPlayer = MediaPlayer.Create (this, Resource.Raw.sound02);
                mediaPlayer.Completion += (senderr, args) => {
                    if (!mediaPlayer.IsPlaying){
                        mediaPlayer.Release();
                        mediaPlayer = null;
                    }
                };  
                mediaPlayer.Start ();   
            };

        }


    }
}
Tagged:

Answers

  • MihaMarkicMihaMarkic SI ✭✭✭✭

    You are doing at least two errors in your code.
    1. Big error: you are using a global field and happily overwritting it each time mediaplayer is still playing and you click a button.
    2. MediaPlayer instance won't go away due to the way you implement its Completion even.

    Here is more correct code (button2 omitted)

    [Activity(Label = "soundrelease", MainLauncher = true, Icon = "@drawable/icon")]
        public class MainActivity : Activity
        {
            protected override void OnCreate(Bundle bundle)
            {
                base.OnCreate(bundle);
    
                // Set our view from the "main" layout resource
                SetContentView(Resource.Layout.Main);
    
                Button button1 = FindViewById<Button>(Resource.Id.MyButton);
                //Button button2 = FindViewById<Button>(Resource.Id.button2);
    
                button1.Click += (object sender, EventArgs e) =>
                {
    
                    MediaPlayer mediaPlayer = MediaPlayer.Create(this, Resource.Raw.test);
                    mediaPlayer.Completion += mediaPlayer_Completion;
                    mediaPlayer.Start();
                };
    
            }
    
            void mediaPlayer_Completion(object sender, EventArgs e)
            {
                MediaPlayer mp = (MediaPlayer)sender;
                mp.Completion -= mediaPlayer_Completion;
                mp.Release();
            }
        }
    
  • kabalkabal AUMember

    namespace soundrelease

    {
    [Activity (Label = "soundrelease", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {

        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
    
            // Set our view from the "main" layout resource
            SetContentView (Resource.Layout.Main);
    
            Button button1 = FindViewById<Button> (Resource.Id.button1);
            Button button2 = FindViewById<Button> (Resource.Id.button2);
    
            button1.Click += (object sender, EventArgs e) =>
            {
    
                MediaPlayer mediaPlayer = MediaPlayer.Create(this, Resource.Raw.sound01);
                mediaPlayer.Completion += mediaPlayer_Completion;
                mediaPlayer.Start();
            };
    
            button2.Click += (object sender, EventArgs e) =>
            {
    
                MediaPlayer mediaPlayer = MediaPlayer.Create(this, Resource.Raw.sound02);
                mediaPlayer.Completion += mediaPlayer_Completion;
                mediaPlayer.Start();
            };
    
        }
        void mediaPlayer_Completion(object sender, EventArgs e)
        {
            MediaPlayer mp = (MediaPlayer)sender;
            mp.Completion -= mediaPlayer_Completion;
            mp.Release();
        }
    
    }
    

    }

  • kabalkabal AUMember

    Same problem, still crashes after around 40 button clicks

  • MihaMarkicMihaMarkic SI ✭✭✭✭

    What does logcat say?

  • kabalkabal AUMember

    Never mind it must have been a problem on my end, your code is working 100%. I can't thank you enough for your help I've been trying to get that to work for ages.
    Since I have around 40 buttons do you know how I could use an array to make my code a lot less bulky? I'm thinking of something like this but I know it's riddled with errors

    protected override void OnCreate (Bundle bundle)
    {
    base.OnCreate (bundle);

            // Set our view from the "main" layout resource
            SetContentView (Resource.Layout.Main);
    

    int buttonIds = { Resource.Id.button1, Resource.Id.button2 };
    int soundIds = { Resource.Raw.sound01, Resource.Raw.sound02 };

            for (int i = 0, n = buttonIds.length(); i < n; i++) {
                Button button = (Button)findViewById(buttonIds[i]);
                button.Click += (object sender, EventArgs e) => {
    
                    MediaPlayer mediaPlayer = MediaPlayer.Create (soundIds[i]);
                    mediaPlayer.Completion += mediaPlayer_Completion;
                    mediaPlayer.Start ();
                };
            }
    

    }
    void mediaPlayer_Completion(object sender, EventArgs e)
    {
    MediaPlayer mp = (MediaPlayer)sender;
    mp.Completion -= mediaPlayer_Completion;
    mp.Release();
    }

    }
    
  • MihaMarkicMihaMarkic SI ✭✭✭✭

    That might work, except for change for loop to code below (int index..) otherwise closure will make all sounds as the last one.

          for (int i = 0, n = buttonIds.length(); i < n; i++) {
                Button button = (Button)findViewById(buttonIds[i]);
            int index = i;
                button.Click += (object sender, EventArgs e) => {
    
                    MediaPlayer mediaPlayer = MediaPlayer.Create (soundIds[index]);
                    mediaPlayer.Completion += mediaPlayer_Completion;
                    mediaPlayer.Start ();
                };
            }
    
  • MihaMarkicMihaMarkic SI ✭✭✭✭

    Right, array has Length property, not length() method, then FindViewById instead of (Button)findViewById and MediaPlayer.Create(this, soundIds[index]).
    Out of my head...

Sign In or Register to comment.