Android 第二次在listview的适配器中播放音频时应用程序崩溃
我的类由包含曲目列表的listview组成。每个列表项由按钮播放和暂停组成。它应该在单击播放时播放曲目,在单击暂停时停止曲目。我没有使用不同的按钮…我只使用一个按钮,在单击b/w播放和暂停时更改其文本,并相应地发挥作用。 我面临以下问题- 单击播放确实会播放曲目,但当我通过单击暂停停止曲目,然后尝试播放任何曲目时,应用程序崩溃并显示以下错误,显示非法状态异常 致命异常:主Android 第二次在listview的适配器中播放音频时应用程序崩溃,android,android-listview,android-mediaplayer,android-adapter,Android,Android Listview,Android Mediaplayer,Android Adapter,我的类由包含曲目列表的listview组成。每个列表项由按钮播放和暂停组成。它应该在单击播放时播放曲目,在单击暂停时停止曲目。我没有使用不同的按钮…我只使用一个按钮,在单击b/w播放和暂停时更改其文本,并相应地发挥作用。 我面临以下问题- 单击播放确实会播放曲目,但当我通过单击暂停停止曲目,然后尝试播放任何曲目时,应用程序崩溃并显示以下错误,显示非法状态异常 致命异常:主 java.lang.IllegalStateException at android.media.Media
java.lang.IllegalStateException
at android.media.MediaPlayer._setDataSource(Native Method)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:966)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:926)
at xyz.SoundCloudAdapter$1.onClick(SoundCloudAdapter.java:86)
at android.view.View.performClick(View.java:4091)
at android.view.View$PerformClick.run(View.java:17072)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
at dalvik.system.NativeStart.main(Native Method)
声音类适配器
公共类SoundCloudAdapter扩展ArrayAdapter实现MediaPlayer.OnPreparedListener{
ArrayList soundcloudList;
拉平机vi;
智力资源
public static MediaPlayer mMediaPlayer;
public SoundCloudAdapter(Context context, int resource, ArrayList<SoundCloud> objects)
{
super(context, resource, objects);
vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Resource = resource;
soundcloudList = objects;
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnPreparedListener(this);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
final ViewHolder holder;
// convert view = design
View v = convertView;
if (v == null)
{
holder = new ViewHolder();
v = vi.inflate(Resource, null);
holder.textview = (TextView) v.findViewById(R.id.name);
holder.btn = (Button) v.findViewById(R.id.button);
holder.btn2 = (Button) v.findViewById(R.id.button2);
holder.textview2 = (TextView) v.findViewById(R.id.email);
v.setTag(holder);
}
else
{
holder = (ViewHolder) v.getTag();
}
holder.textview.setText(soundcloudList.get(position).getTitle());
holder.textview2.setText(soundcloudList.get(position).getId());
holder.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
notifyDataSetChanged();
if (holder.btn.getText().toString().equalsIgnoreCase("Play"))
{
holder.btn.setText("Pause");
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try
{
mMediaPlayer.setDataSource("http://api.soundcloud.com/tracks/"+soundcloudList.get(position).getId()+"/stream?client_id=xyz");
mMediaPlayer.prepareAsync();
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
notifyDataSetChanged();
}
else if (holder.btn.getText().toString().equalsIgnoreCase("Pause"))
{
holder.btn.setText("Play");
if(mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
mMediaPlayer.release();
notifyDataSetChanged();
}
}
});
return v;
}
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
static class ViewHolder
{
public TextView textview;
public Button btn;
public Button btn2;
public TextView textview2;
}
}
曲目不暂停请看以下代码:
holder.btn.setText("Play");
if(mMediaPlayer.isPlaying()) {
mmMediaPlayer.stop();
}
mMediaPlayer.release();
notifyDataSetChanged();
如果要恢复播放,则不应停止并释放MediaPlayer,然后必须再次对其进行初始化。您应仅调用pause方法,该方法会停止播放,但会保留曲目中的当前位置,不会释放资源
此外,请删除releasecall。因为下次单击“播放”时,您仍然希望再次使用相同的曲目
编辑:您还应该检查在播放时运行的代码,您不需要在每次要恢复播放时设置数据源,只要是第一次。查看此代码:
holder.btn.setText("Play");
if(mMediaPlayer.isPlaying()) {
mmMediaPlayer.stop();
}
mMediaPlayer.release();
notifyDataSetChanged();
如果要恢复播放,则不应停止并释放MediaPlayer,然后必须再次对其进行初始化。您应仅调用pause方法,该方法会停止播放,但会保留曲目中的当前位置,不会释放资源
此外,请删除releasecall。因为下次单击“播放”时,您仍然希望再次使用相同的曲目
编辑:您还应该检查在播放时运行的代码,您不需要在每次恢复播放时设置数据源,只要是第一次。尝试在播放和暂停时处理每个列表项的MediaPlayer状态,也不需要将viewHolder对象声明为最终对象,这可能会影响列表项状态
public class SoundCloudAdapter extends BaseAdapter{
private MediaPlayer mMediaPlayer;
private Context context;
private ArrayList<SoundCloud> soundcloudList;
public SoundCloudAdapter(Context context, ArrayList<SoundCloud> soundcloudList){
this.context=context;
this.soundcloudList = soundcloudList;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getCount() {
return soundcloudList.size();
}
@Override
public Object getItem(int position) {
return soundcloudList.get(position);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null){
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.resource, null);
holder.textview = (TextView) convertView.findViewById(R.id.name);
holder.textview2 = (TextView) convertView.findViewById(R.id.email);
holder.btn = (Button) convertView.findViewById(R.id.button);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.textview.setText(soundcloudList.get(position).getTitle());
holder.textview2.setText(soundcloudList.get(position).getId());
holder.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
if(((Button)v).getText().toString().equals("Play")){
try{
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource("http://api.soundcloud.com/tracks/"+soundcloudList.get(position).getId()+"/stream?client_id=e13865f9debacb5f96375fdd96b7fa1b");
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
((Button)v).setText("Pause");
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mMediaPlayer.release();
mMediaPlayer = null;
((Button)v).setText("Play");
}
});
}catch (Exception e){
e.printStackTrace();
}
}else{
mMediaPlayer.release();
mMediaPlayer = null;
((Button)v).setText("Play");
}
notifyDataSetChanged();
}
});
return convertView;
}
static class ViewHolder
{
public TextView textview;
public TextView textview2;
public Button btn;
}
}
每当播放和暂停时,尝试处理每个列表项的MediaPlayer状态,也无需将viewHolder对象声明为最终对象,这可能会影响列表项状态
public class SoundCloudAdapter extends BaseAdapter{
private MediaPlayer mMediaPlayer;
private Context context;
private ArrayList<SoundCloud> soundcloudList;
public SoundCloudAdapter(Context context, ArrayList<SoundCloud> soundcloudList){
this.context=context;
this.soundcloudList = soundcloudList;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getCount() {
return soundcloudList.size();
}
@Override
public Object getItem(int position) {
return soundcloudList.get(position);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null){
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.resource, null);
holder.textview = (TextView) convertView.findViewById(R.id.name);
holder.textview2 = (TextView) convertView.findViewById(R.id.email);
holder.btn = (Button) convertView.findViewById(R.id.button);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.textview.setText(soundcloudList.get(position).getTitle());
holder.textview2.setText(soundcloudList.get(position).getId());
holder.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
if(((Button)v).getText().toString().equals("Play")){
try{
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource("http://api.soundcloud.com/tracks/"+soundcloudList.get(position).getId()+"/stream?client_id=e13865f9debacb5f96375fdd96b7fa1b");
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
((Button)v).setText("Pause");
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mMediaPlayer.release();
mMediaPlayer = null;
((Button)v).setText("Play");
}
});
}catch (Exception e){
e.printStackTrace();
}
}else{
mMediaPlayer.release();
mMediaPlayer = null;
((Button)v).setText("Play");
}
notifyDataSetChanged();
}
});
return convertView;
}
static class ViewHolder
{
public TextView textview;
public TextView textview2;
public Button btn;
}
}
我想你忘记了在“暂停”按钮单击“侦听器”时释放MediaPlayer。@Hareshchelana我没有使用第二个按钮。.我错误地忘记了删除代码。.我只使用了一个按钮,在单击“播放”和“暂停”时更改其文本并相应地运行。.签出更新code@HareshChhelana查看更新的问题。。thanks@HareshChhelana现在跟踪单击暂停时不暂停我认为您忘记了在暂停按钮单击侦听器时释放MediaPlayer。@Hareshchelana我没有使用第二个按钮。.由于错误,我忘记删除代码。.我只使用了一个按钮,在单击b/w播放和暂停时更改其文本并相应地运行。.签出更新code@HareshChhelanaC见鬼去吧更新的问题。。thanks@HareshChhelana现在,单击暂停时不暂停曲目当我单击播放按钮时,曲目开始播放,按钮文本变为暂停,但我面临的一个问题是,如果我向下滚动,然后再次向上滚动,那么我会再次看到按钮文本为播放,而它应为暂停,因为曲目当前正在播放..这意味着按钮状态无法保存,在向下滚动并再次出现时,片段的一部分会再次加载。我应该如何解决问题?我已经解决了上述问题,但我遇到的问题是,如果我将mmediplayer=new MediaPlayer;放入holder.btn.setOnClickListener的onClick中,然后单击多个播放按钮将艺术同时播放多首曲目..所以我把mmediplayer=new MediaPlayer;放在SoundCloudAdapter构造函数中,当我点击播放按钮track stars playing和按钮文本更改为暂停时,我面临以下问题,但我面临的一个问题是,如果我向下滚动,然后再次向上滚动,我会再次看到按钮文本作为播放当曲目正在播放时,应该暂停。这意味着按钮状态不会被保存,在向下滚动和再次出现时,片段的一部分会再次加载。我应该如何解决这个问题?我已经解决了我所问的上述问题,但我面临的问题是,如果我将mmediplayer=new MediaPlayer;放入holder.btn.set的onClick中OnClickListener然后单击多个播放按钮将同时开始播放多首曲目。因此,我将mMediaPlayer=new MediaPlayer;放在SoundCloudAdapter构造函数中,并面临以下问题