多个MediaPlayers一直在失败 - Android studio

时间:2018-05-31 00:05:26

标签: java android android-studio

我是Android和Java开发的新手,我正在寻找设置简单音板应用的一些指导。我正在尝试做什么,并且在让它有效运作方面遇到问题的是处理多个媒体播放器的事件。

例如我正在创建一个音板,当我点击一个按钮时,我希望所有其他声音停止并从内存中释放,我按下的按钮播放其指定的声音。我意识到重复代码块并不是一个好的编程方法,但我也尝试过使用数组和switch语句而效果不大。有关如何在使用多个MediaPlayers时有效释放内存声音的任何指导对我来说都非常有用。我已将下面的代码包含在4个按钮中(我在这个应用程序中超过30个)

public class MainActivity extends AppCompatActivity {


private MediaPlayer Meow1,Meow2,Meow3,Meow4;
private Button meowButton1,meowButton2,meowButton3,meowButton4;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);



 Meow1 = new MediaPlayer();
        Meow1 = MediaPlayer.create(getApplicationContext(), R.raw.meow1);
       // final Boolean Meow1Pause = !Meow1.isPlaying() && Meow1.getCurrentPosition() >1;
        meowButton1 = (Button) findViewById(R.id.Meow1);
        meowButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Meow1.isPlaying())
                { pauseMusic1();
                } else {
                    Meow1.start();
                }}
        });
        Meow1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer Meow1) {
                Meow1.stop();
                Meow1.reset();
                Meow1.release();

            }
        });



       Meow2 = new MediaPlayer();
       Meow2 = MediaPlayer.create(getApplicationContext(), R.raw.meow2);

        meowButton2 = (Button) findViewById(R.id.Meow2);
        meowButton2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Meow2.isPlaying() ){
                    pauseMusic();
                } else {
                    Meow2.start();      
        }}
        });

        Meow2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer Meow1) {
                Meow2.stop();
                Meow2.reset();
                Meow2.release();
            }
        });

        Meow3 = new MediaPlayer();
        Meow3 = MediaPlayer.create(getApplicationContext(), R.raw.meow3);
        meowButton3 = (Button) findViewById(R.id.Meow3);
        meowButton3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Meow3.isPlaying())
                { pauseMusic();
                } else {
                    Meow3.start();
                }}
        });
        Meow3.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer Meow1) {
                Meow3.stop();
                Meow3.reset();
                Meow3.release();

            }
        });

        Meow4 = new MediaPlayer();
        Meow4  = MediaPlayer.create(getApplicationContext(), R.raw.meow4);
        meowButton4 = (Button) findViewById(R.id.Meow4);
        meowButton4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Meow4.isPlaying())
                { pauseMusic();
                } else {
                    Meow4.start();
                }}
        });

}
public void pauseMusic()  {
    if(Meow1 != null && Meow1.isPlaying()) Meow1.pause();
    if(Meow2 != null && Meow2.isPlaying()) Meow2.pause();
    if(Meow3 != null && Meow3.isPlaying()) Meow3.pause();
    if(Meow4 != null && Meow4.isPlaying()) Meow4.pause();
}


}

Run Compiler:
A: Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=SplashScreen, firebase_previous_id(_pi)=-6549553702477848745, firebase_screen_class(_sc)=MainActivity, firebase_screen_id(_si)=-6549553702477848744}]
I/zygote: Do partial code cache collection, code=124KB, data=67KB
I/zygote: After code cache collection, code=124KB, data=67KB
I/zygote: Increasing code cache capacity to 512KB
V/FA: Activity resumed, time: 6376787
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
I/chatty: uid=10085(u0_a85) RenderThread identical 2 lines
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
V/FA: Inactivity, disconnecting from the service
V/MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
               cleanDrmObj: mDrmObj=null mDrmSessionId=null
V/MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
               cleanDrmObj: mDrmObj=null mDrmSessionId=null
D/TAG1: Button 2 pressed
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: g.convery.cat_sounds, PID: 12276
                  java.lang.IllegalStateException
                      at android.media.MediaPlayer.isPlaying(Native Method)
                      at g.convery.cat_sounds.MainActivity$1.onClick(MainActivity.java:97)
                      at android.view.View.performClick(View.java:6256)
                      at android.view.View$PerformClick.run(View.java:24701)
                      at android.os.Handler.handleCallback(Handler.java:789)
                      at android.os.Handler.dispatchMessage(Handler.java:98)
                      at android.os.Looper.loop(Looper.java:164)
                      at android.app.ActivityThread.main(ActivityThread.java:6541)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
W/MediaPlayer-JNI: MediaPlayer finalized without being released
W/MediaPlayer-JNI: MediaPlayer finalized without being released
Application terminated.


LOGCAT:

05-31 09:21:30.099 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
05-31 09:21:30.211 12276-12288/g.convery.cat_sounds I/chatty: uid=10085(u0_a85) FinalizerDaemon identical 33 lines
05-31 09:21:30.212 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
05-31 09:21:30.283 12276-12284/g.convery.cat_sounds I/zygote: Do partial code cache collection, code=124KB, data=67KB
05-31 09:21:30.286 12276-12284/g.convery.cat_sounds I/zygote: After code cache collection, code=124KB, data=67KB
05-31 09:21:30.287 12276-12284/g.convery.cat_sounds I/zygote: Increasing code cache capacity to 512KB
05-31 09:21:31.159 12276-12307/g.convery.cat_sounds I/chatty: uid=10085(u0_a85) RenderThread identical 2 lines
05-31 09:24:41.746 12276-12276/g.convery.cat_sounds E/AndroidRuntime: FATAL EXCEPTION: main
    Process: g.convery.cat_sounds, PID: 12276
    java.lang.IllegalStateException
        at android.media.MediaPlayer.isPlaying(Native Method)
        at g.convery.cat_sounds.MainActivity$1.onClick(MainActivity.java:97)
        at android.view.View.performClick(View.java:6256)
        at android.view.View$PerformClick.run(View.java:24701)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
05-31 09:24:47.955 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
05-31 09:24:47.956 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released

2 个答案:

答案 0 :(得分:0)

发布后您正在使用媒体播放器。从onCompletionListener中删除这些行,然后将它们添加到活动的onDestroy中

Meow1.release();
Meow2.release();
Meow3.release();
Meow4.release();

同时调用create会自动创建一个新实例,您也可以删除这些行

Meow1 = new MediaPlayer();
Meow2 = new MediaPlayer();
Meow3 = new MediaPlayer();
Meow4 = new MediaPlayer();

更好的方法是使用单个媒体播放器并在用户想要播放不同来源时更改日期源,但这种方法在播放音频之前需要一些时间,因为它会每次准备音频,这样做除非您的音频大小非常大,否则可以忽略不计

答案 1 :(得分:0)

  1. 了解您现在如何控制媒体:

    if (Meow4.isPlaying()) { 
        pauseMusic();
    } else {
        Meow4.start();
    }
    

    第一次拨打Meow4.isPlaying()时,您将收到IllegalStateException,因为您的播放器未初始化。

    了解您的MediaPlayer状态是如何定义的并调用适当的函数

  2. 第二点,当遇到重复的块时,你应该想到一个函数。

    Meow3 = new MediaPlayer();
    Meow3 = MediaPlayer.create(getApplicationContext(), R.raw.meow3);
    meowButton3 = (Button) findViewById(R.id.Meow3);
    meowButton3.setOnClickListener(new View.OnClickListener() {
    
    });
    meowButton3.setOnCompletionListener...
    
  3. 在函数中:registerPlayer(Context context, int resourceId, Button controlButton)

    Or with higher level of abstraction, create a subclass of `MediaPlayer` and wrap these logic inside it
    
    1. 你绝对不想一遍又一遍Meow1.pause()。而是将MeoX存储在列表中,然后循环遍历它:

      List<MediaPlayer> players = new ArrayList<>();
      players.add(Meow1);
      ....
      public void pauseMusic()  {
           players.stream().filter(p -> p != null && p.isPlaying()).forEach(p -p.pause());
      }