Android 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();
}
这也是我必须更新和更改我的代码的内容,但这给我传递 playresource() 函数带来了问题。我是否传递错误了,传递的内容应该是私有的吗?
I have read several of the articles on here that suggest using the singleton code, Which I have read and placed into the soundboard as I want to use the singleton code to only allow one mediaplayer instance no matter how many clicks the user defines.
Basically I only want one sound and if the user clicks another button during playback it stops the current sound and plays the one that is pressed. I want only the one MediaPlayer instance but do not understand how to implement it.
Here is the basic idea of my code:
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();
}
This is what I had to update and change my code too but it is giving me a problem with passing the playresource() function. Am I passing it wrong, should it be private that is passing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你不需要单例。您所做的就是每次要播放文件时调用 create 方法。这是错误的,因为您已经有 MediaPlayer 实例。
检查 MediaPlayer.create 实现。
我会这样做:
playResource 方法示例:
当你不再需要MediaPlayer时,你应该释放它。例如在 onPause() 调用中:
我没有对此进行测试,因此可能会出现错误。希望有帮助。
You don't need a Singleton for that. What are you doing is calling create method every time you want to play a file. That's wrong because you already have MediaPlayer instance.
Check MediaPlayer.create implementation.
I would do like that:
playResource method example:
When you don't need MediaPlayer again, you should release it. For example in onPause() call:
I didn't test that so there could be errors. Hope it helps.
getSingletonObject() 方法应返回 MediaPlayer 的实例,该实例是使用 MediaPlayer 的默认构造函数创建的(不指定资源)。
您可以从主类中的 onCreate() 调用 getSingletonObject() 并用它初始化播放器。
稍后在 onClick() 中,您应该调用player.prepare(),然后调用player.setDataSource(),传入资源。
所以,你的代码应该如下所示:
在主类的 onCreate() 方法中,
希望你能自己弄清楚 onClick() 中的代码。并且不要忘记在 onClick() 方法中添加适当的 try..catch 子句。
希望这有帮助!
The getSingletonObject() method should return an instance of MediaPlayer, created using the default constructor for MediaPlayer (without specifying the resource).
You could call getSingletonObject() from onCreate() in the main class and initialize the player with it.
Later in the onClick(), you should call, player.prepare() and then player.setDataSource(), passing in the resource.
So, your code should look something like the below:
In the main class, in the onCreate() method,
Hope you can figure out the code in onClick() by yourself. And don't forget to add the appropriate try..catch clauses in the onClick() method.
Hope this helps!!
我一直在尝试为自己的一个项目解决这个问题。我遇到了同样的问题,在播放第二次时会让应用程序崩溃。
添加
player = new MediaPlayer();
解决了该问题(似乎在 try-catch 块中没有启动媒体播放器)。请参阅下面的代码:
I have been trying to solve this issue for a project of myself. I ran in the same issue that while playing a second playback will let the app crash.
Adding
player = new MediaPlayer();
solved the issue (seems no mediaplayer was initiated in the try-catch block).See the code below: