7

数日前、リリースしたアプリのクラッシュ ログを受け取りました。

エラーは ToneGenerator に由来するもので、問題が見つかりません。

ここでは、カウントダウン タイマーを使用しています。タイマーが 0 になると、アプリは ToneGenerator を起動します。

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)

では、何が問題になるのでしょうか?ToneGenerator に try Catch ブロックがあるかどうかを確認しましたが、ありませんでした。

クラッシュが発生したデバイスに AudioManager.Stream_Notification がなかったのではないかと考えています。

4

3 に答える 3

6

私はここでこれを見つけました:

アプリケーションがメディアプレーヤーリソースを解放していないようです。サウンドの再生が終了したら、MediaPlayer.release()メソッドを呼び出す必要があります。大量のサウンドを高速で再生している場合、ガベージコレクターは追いつくことができません。

于 2012-12-05T08:00:14.560 に答える
2

私も同じ問題を抱えていました。演奏が終わったら音源を離さなければなりません。そのため、ハンドラーはトーンジェネレーターと同じミリ秒で使用してください。

                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (toneGenerator != null) {
                            toneGenerator.release();
                            toneGenerator = null;
                        }
                    }

                }, 2000);
于 2019-02-13T03:18:27.530 に答える
1

私はSoundPoolを使用してプローブを解決しました。短い効果音を再生するには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);
    }
}

ですから、これが頻繁にクラッシュする場合、ToneGeneratorにどのような用途を与えることができるのだろうかと思います。

于 2012-12-13T20:55:01.483 に答える