找到你要的答案

Q:Android: Fragment with listview crashes

Q:安卓:用listview崩溃的片段

I am using a listview in a fragment where I display a number of sounds (like a sound library). When the user clicks any of the items I play the sound. But after a random number of plays the app crashes.

Here is the code to the fragment:

adapter= new soundAdapter(getActivity().getApplicationContext(), contact);

    ListView myList = (ListView)view.findViewById(R.id.listView);
    myList.setAdapter(adapter);
    myList.setOnItemClickListener(
            new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    String clicked = String.valueOf(parent.getItemAtPosition(position));
                    SoundListed k = contact.get(position);
                    if(mySound!=null) {
                        if (mySound.isPlaying()) {
                            mySound.stop();

                        }
                    }
                    mySound = MediaPlayer.create(getActivity(), k.getImage());
                    mySound.start();
                    mySound.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            mySound.release();
                        }
                    });


                }
            });

The SoundListed.class:

     private int _id;
    private String _productname;
   private String _extra;
    private int _image;

    public SoundListed() {

    }

    public SoundListed(int id, String productname, String extra, int image) {
        this._id = id;
        this._productname = productname;
        this._extra = extra;
        this._image=image;
    }

    public SoundListed( String productname, String extra, int image) {
        this._productname = productname;
        this._extra = extra;
        this._image=image;
    }
    public void setID(int id) {
        this._id = id;
    }

    public int getID() {
        return this._id;
    }
    public int getImage(){return this._image;}

    public void setProductName(String productname) {
        this._productname = productname;
    }

    public String getProductName() {
        return this._productname;
    }

    public void setExtra(String extra) {
        this._extra = extra;
    }

    public String getExtra() {
        return this._extra;
    }

Here is my LogCat:

java.lang.IllegalStateException
            at android.media.MediaPlayer.isPlaying(Native Method)
            at com.inc.nicky.messengersayit.SoundFragment$1.onItemClick(SoundFragment.java:90)
            at android.widget.AdapterView.performItemClick(AdapterView.java:308)
            at android.widget.AbsListView.performItemClick(AbsListView.java:1524)
            at android.widget.AbsListView$PerformClick.run(AbsListView.java:3531)
            at android.widget.AbsListView$3.run(AbsListView.java:4898)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5586)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
            at dalvik.system.NativeStart.main(Native Method)

我使用ListView中的一个片段,我在那里显示数量的声音(比如声音库)。当用户单击我播放声音的任何项目时。但随机播放后的应用程序崩溃。

这里是代码的片段:

adapter= new soundAdapter(getActivity().getApplicationContext(), contact);

    ListView myList = (ListView)view.findViewById(R.id.listView);
    myList.setAdapter(adapter);
    myList.setOnItemClickListener(
            new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    String clicked = String.valueOf(parent.getItemAtPosition(position));
                    SoundListed k = contact.get(position);
                    if(mySound!=null) {
                        if (mySound.isPlaying()) {
                            mySound.stop();

                        }
                    }
                    mySound = MediaPlayer.create(getActivity(), k.getImage());
                    mySound.start();
                    mySound.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            mySound.release();
                        }
                    });


                }
            });

SoundListed.class:

     private int _id;
    private String _productname;
   private String _extra;
    private int _image;

    public SoundListed() {

    }

    public SoundListed(int id, String productname, String extra, int image) {
        this._id = id;
        this._productname = productname;
        this._extra = extra;
        this._image=image;
    }

    public SoundListed( String productname, String extra, int image) {
        this._productname = productname;
        this._extra = extra;
        this._image=image;
    }
    public void setID(int id) {
        this._id = id;
    }

    public int getID() {
        return this._id;
    }
    public int getImage(){return this._image;}

    public void setProductName(String productname) {
        this._productname = productname;
    }

    public String getProductName() {
        return this._productname;
    }

    public void setExtra(String extra) {
        this._extra = extra;
    }

    public String getExtra() {
        return this._extra;
    }

这是我的LogCat:

java.lang.IllegalStateException
            at android.media.MediaPlayer.isPlaying(Native Method)
            at com.inc.nicky.messengersayit.SoundFragment$1.onItemClick(SoundFragment.java:90)
            at android.widget.AdapterView.performItemClick(AdapterView.java:308)
            at android.widget.AbsListView.performItemClick(AbsListView.java:1524)
            at android.widget.AbsListView$PerformClick.run(AbsListView.java:3531)
            at android.widget.AbsListView$3.run(AbsListView.java:4898)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5586)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
            at dalvik.system.NativeStart.main(Native Method)
answer1: 回答1:

From docs if the internal player engine has not been initialized or has been released

Your mySound.release(); method is causing IllegalStateException to raise.

Since on completion Resources are released . Try using reset() in place of release() method or You have to create Media Player because After release(), the object is no longer available

从文档如果内部播放器引擎未初始化或已被释放

你的声音对象。release();方法是造成时,提高。

由于完成资源被释放。试着用reset()在release()方法的地方或者你要创建的媒体,在release(),对象不再可用

answer2: 回答2:

As the doc say, isPlaying() can throw IllegalStateException if the internal player engine has not been initialized or has been released.
And in onCompletion you call release() -> isPlaying() will throw exception after that time.
But we don't have any method to get the current state of MediaPlayer.
So I think a work around by try/catch is the only solution:

if (mySound != null) {
        boolean isPlay = false;
        try {
            isPlay = mySound.isPlaying();
        } catch (IllegalStateException e) {
            Log.d("tag", Log.getStackTraceString(e));
            mySound.release();
        }
        if (isPlay) {
            mySound.stop();
        }
    }

As the doc say, isPlaying() can throw IllegalStateException if the internal player engine has not been initialized or has been released.
And in onCompletion you call release() -> isPlaying() will throw exception after that time.
But we don't have any method to get the current state of MediaPlayer.
So I think a work around by try/catch is the only solution:

if (mySound != null) {
        boolean isPlay = false;
        try {
            isPlay = mySound.isPlaying();
        } catch (IllegalStateException e) {
            Log.d("tag", Log.getStackTraceString(e));
            mySound.release();
        }
        if (isPlay) {
            mySound.stop();
        }
    }
android  android-mediaplayer