无法在方法中更改布尔值

时间:2014-05-28 14:10:43

标签: java methods boolean

我有一点问题。我正在使用Java声音采样播放mp3,我想在单击按钮时停止播放。所以我想出了类似的东西:

package sk.umb.osadnici.Client.Core.getterImages;

import java.io.File;
import java.io.IOException;

import java.io.InputStream;
import java.net.URL;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine.Info;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.FloatControl;

import javazoom.jl.player.advanced.AdvancedPlayer;

import static javax.sound.sampled.AudioSystem.getAudioInputStream;
import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED;

public class GetterForBGMusic {
    private SourceDataLine line;
    private URL url;
    public URL bgUrl, bgUUUrl;
    private boolean canPlay = true;


    public void runMusic() {
        final GetterForBGMusic player = new GetterForBGMusic();
        player.play();
    }

    public void play() {
        URL inTTT = getClass().getResource("../sounds/bgMusic.mp3");

        try (AudioInputStream in = getAudioInputStream(inTTT)) {
            AudioFormat outFormat = getOutFormat(in.getFormat());
            Info info = new Info(SourceDataLine.class, outFormat);
            try (SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info)) {
                if (line != null) {
                    System.out.println(canPlay);
                    line.open(outFormat);
                    line.start();
                    stream(getAudioInputStream(outFormat, in), line);
                    line.drain();
                    line.stop();
                }
            }
        } catch (UnsupportedAudioFileException
                | LineUnavailableException
                | IOException e) {
            throw new IllegalStateException(e);
        }
    }

    private AudioFormat getOutFormat(AudioFormat inFormat) {
        final int ch = inFormat.getChannels();
        final float rate = inFormat.getSampleRate();
        return new AudioFormat(PCM_SIGNED, rate, 16, ch, ch * 2, rate, false);
    }

    private void stream(AudioInputStream in, SourceDataLine line)
            throws IOException {
        while (true) {
            System.out.println(this.getCanPlay());
        }
    }

    public void setCanPlay(boolean play) {
        this.canPlay = play;
    }

    public boolean getCanPlay() {
        return canPlay;
    }

    private void booleanValue() {
        while (true)
            System.out.println(canPlay);
    }
}

我使用这段代码,如果我在构造函数中调用booleanValue方法,一切都很好。但如果在流内部调用此方法,则值更改后不会发生更改。

或者有人可以告诉我如何制止这种情况:http://odoepner.wordpress.com/2013/07/19/play-mp3-or-ogg-using-javax-sound-sampled-mp3spi-vorbisspi/

1 个答案:

答案 0 :(得分:1)

你的程序是单线程的,这意味着它执行你从上到下编程的“命令”序列。

例如,在此示例中

setCanPlay(true);
play(); //your for loop
setCanPlay(false);

setCanPlay(false)指令仅在for循环执行完毕后执行。

您需要的是让for循环在后台运行,并且能够在for循环运行时修改 canPlay 。这称为多线程,您应该在java api doc中查找Runnable,Task和Service类,以了解如何实现它。

你最终会得到这样的东西:

setCanPlay(true);
play(); //your for loop, launched in another thread.
setCanPlay(false); // Executed while the for loop is running

这会立即开始和结束比赛。

多线程是唯一方式来停止执行程序(从外部)。