Android MediaPlayer Singleton

mr.*_*hua 4 singleton android onclick android-mediaplayer

我已经阅读了几篇建议使用单例代码的文章,由于我想使用单例代码仅允许一个mediaplayer实例(无论用户定义了多少次点击),因此已阅读并放置在音板中。

基本上,我只想要一个声音,如果用户在播放期间单击另一个按钮,它将停止当前声音并播放被按下的声音。我只需要一个MediaPlayer实例,但不了解如何实现它。

这是我的代码的基本思想:

    package com.example.context;

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;




    import android.app.Activity;
    import android.content.ContentValues;
    import android.content.Intent;
    import android.media.MediaPlayer;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.MediaStore;
    import android.view.ContextMenu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ContextMenu.ContextMenuInfo;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;

    public class main extends Activity implements OnClickListener {

    MediaPlayer player;

    int[] ressound ={R.raw.boomstick, R.raw.chainsaw, R.raw.shebitch, R.raw.byebye,
    R.raw.comegetsome, R.raw.groovy, R.raw.shoelace, R.raw.smart,   R.raw.yeahbaby};//added as needed
    int j=0;
    private static final String TAG = "MyTag";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


     //Coding for all buttons, registers, and Listeners
        Button btn1 = (Button) findViewById(R.id.btn1);
        registerForContextMenu(btn1); 
        btn1.setOnClickListener(this);
        Button btn2 = (Button) findViewById(R.id.btn2);
        registerForContextMenu(btn2);
        btn2.setOnClickListener(this);
        Button btn3 = (Button) findViewById(R.id.btn3);
        registerForContextMenu(btn3);
        btn3.setOnClickListener(this);

    }

     //On click Handlers for multiple buttons 
        public void onClick(View v) {
        switch(v.getId()){
        case R.id.btn1:
        // action to perform on button 1
        j = 0;
        playResource();
        break;
    case R.id.btn2:
        // action to perform on button 1
        j = 1;
        playResource();
        break;
    case R.id.btn3:
        // action to perform on button 1    
        j = 2;
        playResource();
        break;

    }
         public void playResource(int j, int resource) {
    this.j = j;
    if (player != null) {
        if (player.isPlaying())
            player.stop();
        player.reset();
        //from MediaPlayer implementation (link above)
        try {
            AssetFileDescriptor afd = getResources().openRawResourceFd(resource);
            if (afd == null) return;
            player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            afd.close();
            player.prepare();
        } catch (IOException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        } catch (SecurityException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        }
    }
    else {
        //player is null
        //it will create new MediaPlayer instance, setDataSource and call prepare
        player = MediaPlayer.create(this, resource);
    }
    //if everything ok play file
    //in case of any error return from method before (catch)
    player.start();
}
Run Code Online (Sandbox Code Playgroud)

这也是我必须更新和更改代码的原因,但是它给我传递playresource()函数带来了问题。如果传递的是私密的,我是否会错误地传递它。

zok*_*oki 6

您不需要为此的Singleton。您在做什么,每次要播放文件时都调用create方法。这是错误的,因为您已经有MediaPlayer实例。检查MediaPlayer.create实现。我会这样:

  • 创建新方法playResource(int j,int resource)
  • 在每种情况下,R.id.btnX我都会调用方法playResource(X,R.raw.Y)-X和Y取决于btn

playResource方法示例:

private static final String TAG = "MyTag";
playResource(int j, int resource) {
    this.j = j;
    if (player != null) {
        if (player.isPlaying())
            player.stop();
        player.reset();
        //from MediaPlayer implementation (link above)
        try {
            AssetFileDescriptor afd = getResources().openRawResourceFd(resource);
            if (afd == null) return null;
            player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            afd.close();
            player.prepare();
        } catch (IOException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        } catch (SecurityException ex) {
            Log.d(TAG, "create failed:", ex);
            // failed: return
        }
    }
    else {
        //player is null
        //it will create new MediaPlayer instance, setDataSource and call prepare
        player = MediaPlayer.create(this, resource);
    }
    //if everything ok play file
    //in case of any error return from method before (catch)
    player.start();
}
Run Code Online (Sandbox Code Playgroud)

当不再需要MediaPlayer时,应释放它。例如在onPause()调用中:

if (player != null) {
    player.release();
    player = null;
} 
Run Code Online (Sandbox Code Playgroud)

我没有测试,所以可能会有错误。希望能帮助到你。