Android 发电机崩溃
几天前,我在发布的应用程序上收到了一个崩溃日志 错误来自ToneGenerator,我找不到问题所在 在这里,我有一个倒计时计时器,当计时器达到0时,应用程序启动一个ToneGeneratorAndroid 发电机崩溃,android,audio,crash,Android,Audio,Crash,几天前,我在发布的应用程序上收到了一个崩溃日志 错误来自ToneGenerator,我找不到问题所在 在这里,我有一个倒计时计时器,当计时器达到0时,应用程序启动一个ToneGenerator private void lanceMinuteur(int temps, int color){ if(color == 0) minuteur.setTextColor(getResources().getColor(R.color.color_important));
private void lanceMinuteur(int temps, int color){
if(color == 0)
minuteur.setTextColor(getResources().getColor(R.color.color_important));
else
minuteur.setTextColor(getResources().getColor(R.color.color_informative));
if(chronoLance){
chrono.cancel();
}
chronoLance = true;
chrono = new CountDownTimer((temps + 1) * 1000, 1000) {
public void onTick(long millisUntilFinished) {
minuteur.setText(String.valueOf(millisUntilFinished / 1000) + "\"");
}
public void onFinish() {
minuteur.setText("0\"");
minuteur.setTextColor(getResources().getColor(R.color.textcolor1design));
chronoLance = false;
final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100); //The error is coming from here
tg.startTone(ToneGenerator.TONE_PROP_ACK);
}
}.start();
}
以及我收到的事故日志:
java.lang.RuntimeException: Init failed
at android.media.ToneGenerator.native_setup(Native Method)
at android.media.ToneGenerator.<init>(ToneGenerator.java:798)
at ma.myperf.musculation.activ.GoPerformanceActivity$2.onFinish(GoPerformanceActivity.java:350)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:118)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:4385)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException:初始化失败
在android.media.ToneGenerator.native_设置中(本机方法)
位于android.media.ToneGenerator(ToneGenerator.java:798)
在ma.myperf.musculation.activ.GoPerformanceActivity$2.onFinish(GoPerformanceActivity.java:350)
位于android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:118)
位于android.os.Handler.dispatchMessage(Handler.java:99)
位于android.os.Looper.loop(Looper.java:150)
位于android.app.ActivityThread.main(ActivityThread.java:4385)
位于java.lang.reflect.Method.Invokenactive(本机方法)
位于java.lang.reflect.Method.invoke(Method.java:507)
在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)上
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
在dalvik.system.NativeStart.main(本机方法)
那么问题出在哪里呢?我检查过ToneGenerator是否有试接挡块,但没有
我想可能发生崩溃的设备没有AudioManager.Stream\u通知?我发现:
听起来您的应用程序没有发布媒体播放器
资源。播放完声音后,需要调用
release()方法。如果你播放了很多声音
很快,垃圾收集器就跟不上了 我使用了一个声音池来解决我的问题。我读到SoundManager是播放短音效的最佳选择,所以我使用了这里发布的解决方案,因为ToneGenerator看起来太不稳定了
public void initSounds(Context theContext, int nbMaxSons) {
mContext = theContext;
mSoundPool = new SoundPool(nbMaxSons, AudioManager.STREAM_MUSIC, 0);
mSoundPoolMap = new HashMap<Integer, Integer>();
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
}
public void addSound(int index, int soundID) {
mAvailibleSounds.add(index);
mSoundPoolMap.put(index, mSoundPool.load(mContext, soundID, 1));
}
public void playSound(int index) {
// dont have a sound for this obj, return.
if (mAvailibleSounds.contains(index)) {
int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int soundId = mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f);
mKillSoundQueue.add(soundId);
// schedule the current sound to stop after set milliseconds
mHandler.postDelayed(new Runnable() {
public void run() {
if (!mKillSoundQueue.isEmpty()) {
mSoundPool.stop(mKillSoundQueue.firstElement());
}
}
}, 3000);
}
}
public void initSounds(上下文,int-nbMaxSons){
mContext=上下文;
mSoundPool=新的声音池(nbMaxSons,AudioManager.STREAM_MUSIC,0);
mSoundPoolMap=newhashmap();
mAudioManager=(AudioManager)mContext.getSystemService(Context.AUDIO\u服务);
}
公共void addSound(int索引,int soundID){
mAvailibleSounds.add(索引);
mSoundPoolMap.put(索引,mSoundPool.load(mContext,soundID,1));
}
公共虚空播放声音(整数索引){
//没有这个obj的声音,返回。
if(mAvailibleSounds.contains(索引)){
int streamVolume=mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int soundId=mSoundPool.play(mSoundPoolMap.get(index),streamVolume,streamVolume,1,0,1f);
mKillSoundQueue.add(soundId);
//计划当前声音在设置的毫秒后停止
mHandler.postDelayed(新的Runnable(){
公开募捐{
如果(!mKillSoundQueue.isEmpty()){
mSoundPool.stop(mKillSoundQueue.firstElement());
}
}
}, 3000);
}
}
因此,我想知道当ToneGenerator如此频繁地崩溃时,该如何使用它。我也有同样的问题。完成后,您必须释放音调发生器。因此,使用与音调生成器具有相同毫秒数的处理程序
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (toneGenerator != null) {
toneGenerator.release();
toneGenerator = null;
}
}
}, 2000);
这里也有同样的问题:(你在
GoPerformanceActivity.java
第350行的代码是什么?第350行是这一行的最后一个ToneGenerator tg=new ToneGenerator(AudioManager.STREAM\u NOTIFICATION,100);我把它放在这里“//错误来自这里”我想你是对的:但我们什么时候才能确切知道声音何时播放完毕?这一定是实际的解决方案,也是问题的答案。它帮助我在2020年解决了拨号器发电机的问题