Android MediaPlayer 使用大量资源

标签 android multithreading service audio

我正在使用 OpenGL 2.0 制作游戏,但我遇到了声音问题,因为声音会减慢我的应用程序的速度,并且 FPS 会降低大约 20 帧。我为声音实现服务并在新线程上运行它,但问题是一样的。 MediaServer 使用的 CPU 比我的带有很多 Sprite 的应用程序要多。
我只播放三个总大小小于 0.5 MB 的声音。
这是我的代码:

package com.filsoft.mouse;

import java.io.IOException;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;

public class Sound extends Service implements OnCompletionListener {
      private final IBinder mBinder = new LocalBinder();
      private Looper mServiceLooper;
      private ServiceHandler mServiceHandler;
    // Handler that receives messages from the thread
      private final class ServiceHandler extends Handler {
          MediaPlayer[] mediaPlayer=new MediaPlayer[3];
          public ServiceHandler(Looper looper) {
              super(looper);
            mediaPlayer[0] = MediaPlayer.create(getApplicationContext(), R.raw.sound1);
            mediaPlayer[0].setLooping(true);

            mediaPlayer[1] = MediaPlayer.create(getApplicationContext(), R.raw.sound1);
            mediaPlayer[1].setLooping(true);

            mediaPlayer[2] = MediaPlayer.create(getApplicationContext(), R.raw.sound1);
            mediaPlayer[2].setLooping(true);
                try {
                    for(int i=0;i<3;i++)
mediaPlayer[i].prepare();
                } catch (IllegalStateException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }


          }
          @Override
          public void handleMessage(Message msg) {
              play(msg.arg1);
          }
          public void stopAll()
          {
               if (mediaPlayer[0].isPlaying()) {
                      mediaPlayer[0].pause();
                    }
                    if (mediaPlayer[1].isPlaying()) {
                          mediaPlayer[1].pause();
                    }
                    if (mediaPlayer[2].isPlaying()) {
                          mediaPlayer[2].pause();
                    }
          }
          public void play(int idx)
          {
              stopAll();
              if (!mediaPlayer[idx].isPlaying()) {
                  mediaPlayer[idx].start();
                }
          }

      }

      @Override
      public IBinder onBind(Intent intent) {
        return mBinder;
      }

      @Override
      public void onCreate() {
          HandlerThread thread = new HandlerThread("Audio",
                    Process.THREAD_PRIORITY_URGENT_AUDIO);
            thread.start();

            // Get the HandlerThread's Looper and use it for our Handler
            mServiceLooper = thread.getLooper();
            mServiceHandler = new ServiceHandler(mServiceLooper);

        }
      public void startPlay(int idx)
      {
          Message msg = mServiceHandler.obtainMessage();
          msg.arg1 = idx;
          mServiceHandler.sendMessage(msg);

      }
      public class LocalBinder extends Binder {
            public Sound getService() {
                return Sound.this;
            }

        }
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {


        return START_STICKY;
      }

      public void onDestroy() {

      }

      public void onCompletion(MediaPlayer _mediaPlayer) {
        stopSelf();
      }

    }

最佳答案

而不是创建多个 MediaPlayer s,你应该使用 SoundPool - 专门设计用于同时播放多个流的类,例如在游戏中发现的。循环声音也很容易:

Sounds can be looped by setting a non-zero loop value. A value of -1 causes the sound to loop forever. In this case, the application must explicitly call the stop() function to stop the sound. Any other non-zero value will cause the sound to repeat the specified number of times, e.g. a value of 3 causes the sound to play a total of 4 times.

关于Android MediaPlayer 使用大量资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25353750/

相关文章:

java - Android,前台服务是否使应用程序保持 Activity 状态?

android - Awareness.SnapshotApi.getLocation 中的 onResult() 未从服务调用

c++ - 对于具有 UIAccess ="true"的进程,CreateProcessAsUser 失败并显示 ERROR_ELEVATION_REQUIRED

java - 有很多 getters & setters 是个好主意吗?

android - 使用 Android 客户端的 Orion Context Broker 上下文订阅

Java RMI 和线程同步问题

wpf - 在单个 WPF 线程中加载多个模块

java - 如何在同一个程序中使用onclick和onclicklistener?

android - 如何从不同的 Activity 访问 SQL 数据库?

java - 使用 GeoTools 加载多线程几何图形