gpt4 book ai didi

android - SoundManager 中偶尔出现 NullPointerException

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:55:48 29 4
gpt4 key购买 nike

我使用这个标准的 SoundManager。它在我所有的设备上都能正常工作,但只是偶尔在市场上出现这些错误

  1. SoundManager.playSound(SoundManager.java:87) 中的 NullPointerException

  2. SoundManager.cleanup(SoundManager.java:107) 中的 NullPointerException

代码如下:

public class SoundManager {

private static SoundManager _instance;
private static SoundPool mSoundPool;
private static HashMap<Integer, Integer> mSoundPoolMap;
private static AudioManager mAudioManager;
private static Context mContext;

private SoundManager(){ }

static synchronized public SoundManager getInstance(){
if (_instance == null)
_instance = new SoundManager();
return _instance;
}


public static void initSounds(Context theContext){
mContext = theContext;
mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
mSoundPoolMap = new HashMap<Integer, Integer>();
mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
}


public static void addSound(int Index,int SoundID){
mSoundPoolMap.put(Index, mSoundPool.load(mContext, SoundID, 1));
}


public static void loadSounds(){

mSoundPoolMap.put(1, mSoundPool.load(mContext, R.raw.kick1, 1));
mSoundPoolMap.put(2, mSoundPool.load(mContext, R.raw.kick2, 1));
mSoundPoolMap.put(3, mSoundPool.load(mContext, R.raw.kick3, 1));


}


public static void playSound(int index, float volume){
**line 87:** float streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
streamVolume = streamVolume / mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
mSoundPool.play(mSoundPoolMap.get(index), streamVolume*volume, streamVolume*volume, 1, 0, 1);
}


public static void stopSound(int index){
mSoundPool.stop(mSoundPoolMap.get(index));
}

public static void cleanup(){
**line 107:** mSoundPool.release();
mSoundPool = null;
mSoundPoolMap.clear();
mAudioManager.unloadSoundEffects();
_instance = null;

}
}

这是启动 Activity 中的清理调用:

    //REMOVE SOUND MEMORY ALLOCATION
@Override
public void onDestroy()
{
super.onDestroy();
SoundManager.cleanup();
}

有谁知道是什么原因导致这些偶尔出现的罕见错误以及如何预防这些错误?这发生在我所有使用此 SoundManager 的应用程序中......即使是有点奇怪的猜测也会有所帮助。

最佳答案

当您初始化 SoundManager 时,请使用 Application Context。您可能在 Activity 之间移动时遇到问题。如果 SoundManager 比您的 Activity 生命周期更长。您甚至可以在您的应用程序中进行初始化。

public class MyAndroidApp extends Application {
@Override
public void onCreate() {
super.onCreate();
SoundManager.initSounds(this);
}
}

我也同意 WarrenFaith 的观点。唯一的静态变量应该是 _instance 和 getInstance()。

此外,如果您在 Application 类中加载声音,则无需担心同步问题。

如果对您有帮助,您可以查看我使用的代码。它利用来自 http://code.google.com/p/opensl-soundpool/ 的 OpenSL SoundPool 库

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;

import com.kytomaki.openslsoundpool.JavaSoundPool;
import com.kytomaki.openslsoundpool.OpenSLSoundPool;
import com.kytomaki.openslsoundpool.SoundPoolIf;

final public class SoundManager
{
// Predetermined sound ID's
public static final int NO_SOUND = -1 ;
public static final int WINNER = -2 ;

// Tag for logging
protected static final String TAG = "SoundManager" ;

/** Used to load and play sounds **/
private Context context ;

/** Sound can be disable from separate thread **/
private final AtomicBoolean useSound ;

// Sound Arrays
private final ArrayList<Integer> winningSounds ;
private final SoundPoolIf soundPool ;
private final HashMap<Integer, Integer> soundPoolMap ;
private final AudioManager audioManager ;

/** Singleton object for sound play back **/
private static SoundManager soundManagerInstance ;


private static final int USE_SOUNDPOOL = 1 ;
private static final int USE_OPENSL = 2 ;
private static int use = USE_SOUNDPOOL ;



/**
* Private Method to create a new SoundManager<br>
* This is a Singleton Object
* @param context Should be the Application Context
*/
private SoundManager( final Context context )
{
setContext( context ) ;
useSound = new AtomicBoolean( true ) ;
audioManager = (AudioManager) context.getSystemService( Context.AUDIO_SERVICE ) ;

soundPoolMap = new HashMap<Integer, Integer>() ;
winningSounds = new ArrayList<Integer>() ;

if ( use == USE_OPENSL )
{
soundPool = new OpenSLSoundPool( 2, OpenSLSoundPool.RATE_44_1, OpenSLSoundPool.FORMAT_16, 1) ;
} else {
soundPool = new JavaSoundPool( 2 ) ;
}
}

/**
* Must be called before using<br>
* Best to initialize in Application Class
* @param context
*/
public static void initSoundManager( final Context context )
{
if ( soundManagerInstance == null )
{
soundManagerInstance = new SoundManager( context ) ;
}
else
{
throw new UnsupportedOperationException( "Sound manager has already been created" ) ;
}
}

/**
* Overloaded method to allow use of OpenSL
* @param context
* @param useOpenSL
*/
public static void initSoundManager( final Context context, final boolean useOpenSL){
if(useOpenSL){
use = USE_OPENSL;
}
initSoundManager(context);
}

/**
* Must initialize first with {@link SoundManager#initSoundManager(Context)}
* @return instance of SoundManager
*/
public static SoundManager getSoundManagerInstance()
{
if ( soundManagerInstance != null )
{
return soundManagerInstance ;
}
else
{
throw new UnsupportedOperationException( "SoundManager must be initalized" ) ;
}
}


/**
* Add a sound from an android resource file R.id.sound<br>
* To be played back with SoundManager.play(soundId)
* @param soundId
* @param soundResourceId
*/
public void addSound( final int soundId, final int soundResourceId )
{
soundPoolMap.put(soundId, soundPool.load(getContext(), soundResourceId));
}

/**
* Adds a winning sound from a resource to be played at random<br>
* Called by SoundManager.play(WINNER)
* @param soundResourceId
*/
public void addWinningSound( final int soundResourceId )
{
winningSounds.add( soundResourceId ) ;
}

/**
* Plays a sound first checking if sound is enabled
* @param soundToPlay soundId or WINNER to play random winning sound
*/
public synchronized void play( final int soundToPlay )
{
if ( isUseSound() )
{
switch ( soundToPlay )
{
case NO_SOUND :
break ;
case WINNER :
// Play a random winning sound using media player
final MediaPlayer mp ;
mp = MediaPlayer.create( getContext(), randomWinnerSound() ) ;
if ( mp != null )
{
mp.seekTo( 0 ) ;
mp.start() ;
}
break ;
default :
playSound( soundToPlay ) ;
break ;
}
}
}

/**
* Calls soundpool.play
* @param soundToPlay
*/
private void playSound( final int soundToPlay )
{
float streamVolume = audioManager.getStreamVolume( AudioManager.STREAM_MUSIC ) ;
streamVolume = streamVolume / audioManager.getStreamMaxVolume( AudioManager.STREAM_MUSIC ) ;
soundPool.play(soundPoolMap.get(soundToPlay), streamVolume);
}

/**
* @return random winning sound position
*/
private int randomWinnerSound()
{
final Random rand = new Random() ;
final int playNumber = rand.nextInt( winningSounds.size() ) ;
return winningSounds.get( playNumber ) ;
}

/**
* @param context the context to set
*/
private final void setContext( final Context context )
{
this.context = context ;
}

/**
* @return the context
*/
private final Context getContext()
{
return context ;
}

/**
* @param useSound false to disable sound
*/
public final void setUseSound( final boolean useSound )
{
this.useSound.set( useSound ) ;
}

/**
* @return the useSound
*/
public boolean isUseSound()
{
return useSound.get() ;
}


}

仍在进行中,但已完成工作。

关于android - SoundManager 中偶尔出现 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11917595/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com