मैं एक ऑडियो फ़ाइल चलाने के लिए MediaPlayer पर काम कर रहा हूँ

वर्तमान में मुख्य सूत्र पर काम करता है

 public boolean playFile(String path) {
    MediaPlayer mp = new MediaPlayer();
    mp.setAudioAttributes(AudioFocusManager.getPlaybackAttributes());
    try {
        mp.setDataSource(path);
        mp.prepare();
        mp.start();
        mp.setOnErrorListener((mp1, what, extra) -> {
            return true;
        });
        mp.setOnCompletionListener( mp1 -> {
        });
        return true;
    } catch (Exception e) {
        return false;
    }
}

लेकिन मैं इसे एक निष्पादक के पास ले जाने की कोशिश कर रहा हूँ

    ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.execute(() -> {

    });

एक बार जब मैं इसे निष्पादक के पास ले जाता हूं, तो दूसरा और तीसरा रिटर्न एक त्रुटि उत्पन्न करता है

अप्रत्याशित वापसी मूल्य

और playFile निम्नलिखित को ट्रिगर करता है

लापता वापसी विवरण

मैंने AtomicReference का उपयोग करने का प्रयास किया है

AtomicReference<Boolean> correctlyPlayed = new AtomicReference<>(false);
    //set up MediaPlayer
    ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.execute(() -> {
        MediaPlayer mp = new MediaPlayer();
        mp.setAudioAttributes(AudioFocusManager.getPlaybackAttributes());
        try {
            mp.setDataSource(path);
            mp.prepare();
            mp.start();
            mp.setOnErrorListener((mp1, what, extra) -> {
                return true;
            });
            mp.setOnCompletionListener( mp1 -> {
            });
            correctlyPlayed.set(true);
        } catch (Exception e) {
            AudioFocusManager.releaseAudioFocus();
            correctlyPlayed.set(false);
        }
    });

    return correctlyPlayed.get(); 

लेकिन यह हमेशा झूठा ट्रिगर करता है, जिसका अर्थ है कि यह थ्रेड को अपडेट करने की प्रतीक्षा नहीं करता है

मैं इसे कैसे कर सकता था?

0
bellotas 26 नवम्बर 2021, 13:51
जब आप दूसरी और तीसरी बार दौड़ते हैं तो सटीक अपवाद क्या होता है? क्या आप उस अपवाद और संदेश को पोस्ट कर सकते हैं? यदि यह केवल "मीडिया फ़ाइल उपयोग में है" या कुछ और है, तो यह जावा से संबंधित समस्या नहीं है। आइए पहले इसे साफ करें।
 – 
Sree Kumar
26 नवम्बर 2021, 14:16
आपको execute के बजाय submit का उपयोग करना चाहिए, क्योंकि यह एक Future देता है, जिसके साथ आप कार्य का प्रबंधन कर सकते हैं।
 – 
MC Emperor
26 नवम्बर 2021, 14:20

2 जवाब

सबसे बढ़िया उत्तर

जैसा कि टिप्पणी में कहा गया है, executor#execute के बजाय executor#submit का उपयोग करें, ताकि आप एक Future प्राप्त कर सकें, और आप परिणाम प्राप्त करने के लिए Future#get पर कॉल कर सकते हैं:

       Future<Boolean> future = executor.submit(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                // ...
                return true;
            }
        });
        return future.get(); // block until get result
2
zysaaa 26 नवम्बर 2021, 14:47

निष्पादन विधि के लिए एक रननेबल की आवश्यकता होती है और एक रननेबल कुछ भी वापस नहीं करता है, इसलिए आपको अप्रत्याशित वापसी मान त्रुटि मिलती है। आप अपने प्लेफाइल का रिटर्न वैल्यू सीधे इस तरह एक अलग थ्रेड से नहीं प्राप्त कर सकते हैं, लेकिन परमाणु संदर्भ के साथ आपका दृष्टिकोण काम करना चाहिए। बूलियन मूल्यों के लिए एक अंतर्निहित परमाणु प्रकार है, परमाणु बूलियन, इसके बजाय इसका उपयोग करने पर विचार करें।

इसे बदलने का प्रयास करें:

mp.setOnErrorListener((mp1, what, extra) -> {
    return true;
});

इसके लिए:

mp.setOnErrorListener((mp1, what, extra) -> {
    correctlyPlayed.set(true);
});

साथ ही, हो सकता है कि आप लौटने से पहले अन्य थ्रेड के निष्पादन के लिए प्रतीक्षा करने के लिए अपने कोड को सिंक्रनाइज़ करना चाहें, इसके लिए, कुछ सेमाफोर सिंक्रनाइज़ेशन तकनीकों (उदा। रिटर्न वैल्यू के रूप में हमेशा गलत होने के पीछे का कारण संभवतः एक सिंक्रोनाइज़ेशन समस्या है, जैसा कि आपने सही बताया।

1
Toni Nagy 26 नवम्बर 2021, 14:17