2017-06-17 117 views
0

嗨我正在建立一个响应原生android模块的音乐流。当我尝试播放音乐时,它会与我加载的第一个URL一起工作,但当我尝试加载另一个URL时,该应用程序会崩溃。Android音乐流式播放器

下面是该模块的代码。

package com.mediaplayer; 

import android.media.AudioManager; 
import android.media.MediaPlayer; 
import android.os.AsyncTask; 

import com.facebook.react.bridge.ReactApplicationContext; 
import com.facebook.react.bridge.ReactContextBaseJavaModule; 
import com.facebook.react.bridge.ReactMethod; 

import java.io.IOException; 

public class MediaPlayerModule extends ReactContextBaseJavaModule { 
    String stream = "http://stream.radioreklama.bg:80/radio1rock128"; 
    boolean prepared = false; 
    boolean started = false; 

    MediaPlayer mediaPlayer; 
    PlayerTask playerTask; 

    public MediaPlayerModule(ReactApplicationContext reactContext) { 
     super(reactContext); 
     mediaPlayer = new MediaPlayer(); 
     mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    } 

    @Override 
    public String getName() { 
     return "MediaPlayerModule"; 
    } 


    @ReactMethod 
    public void play(String url) { 
     if(prepared){ 
      mediaPlayer.reset(); 
      mediaPlayer.release(); 
     } 
     playerTask = new PlayerTask(); 
     playerTask.execute(url); 
    } 


    @ReactMethod 
    public void pause() { 

     if(mediaPlayer != null){ 
      mediaPlayer.reset(); 
      mediaPlayer.release(); 
      mediaPlayer = null; 
     } 
    } 

    @ReactMethod 
    public void resume() { 
     if (started) { 
      mediaPlayer.start(); 
     } 
    } 

    @ReactMethod 
    public void destroy() { 
     if (prepared) { 
      mediaPlayer.release(); 
      started = false; 
     } 
    } 

    class PlayerTask extends AsyncTask<String, Void, Boolean> { 
     @Override 
     protected Boolean doInBackground(String... strings) { 
      Boolean prepared = false; 

       try { 
        mediaPlayer.setDataSource(strings[0]); 
        mediaPlayer.prepare(); 
        prepared = true; 
       } catch (IOException e) { 
        e.printStackTrace(); 
        prepared = false; 
       } 

      return prepared; 
     } 

     @Override 
     protected void onPostExecute(Boolean aBoolean) { 
      super.onPostExecute(aBoolean); 
      mediaPlayer.start(); 
      started = true; 

     } 
    } 
} 

有一个页面包含歌曲及其URL。当我在第一页上选择一首歌曲时,它会用歌曲的URL导航到第二页。下面是第二页的js代码(播放的歌曲的页面):

var mp = require('react-native').NativeModules.MediaPlayerModule; 

export default class Player extends Component { 

    constructor(props) { 
     super(props); 
     this.state = { 
      image: this.props.navigation.state.params.image, 
      title: this.props.navigation.state.params.title, 
      artistes: this.props.navigation.state.params.artistes, 
      mp3Url:this.props.navigation.state.params.mp3Url 
     } 
    } 

    componentDidMount(){ 
     mp.play(this.state.mp3Url); 
    } 
} 

编辑:这里是logcat的:

--------- beginning of crash 
06-17 07:21:28.544 2406-2432/com.downstream E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3 
                   Process: com.downstream, PID: 2406 
                   java.lang.RuntimeException: An error occurred while executing doInBackground() 
                    at android.os.AsyncTask$3.done(AsyncTask.java:309) 
                    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) 
                    at java.util.concurrent.FutureTask.setException(FutureTask.java:223) 
                    at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
                    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
                    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                    at java.lang.Thread.run(Thread.java:818) 
                   Caused by: java.lang.IllegalStateException 
                    at android.media.MediaPlayer.nativeSetDataSource(Native Method) 
                    at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1085) 
                    at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1046) 
                    at com.mediaplayer.MediaPlayerModule$PlayerTask.doInBackground(MediaPlayerModule.java:118) 
                    at com.mediaplayer.MediaPlayerModule$PlayerTask.doInBackground(MediaPlayerModule.java:112) 
                    at android.os.AsyncTask$2.call(AsyncTask.java:295) 
                    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
                    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)  
                    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)  
                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)  
                    at java.lang.Thread.run(Thread.java:818)  
06-17 07:21:28.914 2406-2428/com.downstream E/Surface: getSlotFromBufferLocked: unknown buffer: 0xae6b5f10 

回答

1

也许当你玩第二部曲接下来的时间内崩溃,因为,它可能会获得Mediaplayer的“NULL”对象。请发布您的logcat崩溃,以便我可以更确定我的答案。

+0

我已经添加了logcat的 – digiwebguy

+0

“布尔准备= FALSE; “从“doInBackground()”中删除这一行。媒体播放器无法重置为“public void play(String url)”,因为'prepare'始终保持为“false”。删除上面的行将直接访问你的全球“准备”。 –

+0

谢谢。我不知道我是如何错过的。我删除它,但它仍然崩溃,但:/ – digiwebguy

0

@Rahul Gupta的评论让我以正确的方式思考问题。所以问题是我在做错误的地方准备检查。我所需要做的就是将if(prepared)else块移动到我的异步任务中,并解决了问题。下面的代码:

这就是玩儿法貌似现在:

@ReactMethod 
public void play(String url) { 
    playerTask = new PlayerTask(); 
    playerTask.execute(url); 
} 

和这里的异步任务:

class PlayerTask extends AsyncTask<String, Void, Boolean> { 
    @Override 
    protected Boolean doInBackground(String... strings) { 

     if(prepared){ 
      mediaPlayer.reset(); 
     } 

     try { 
      mediaPlayer.setDataSource(strings[0]); 
      mediaPlayer.prepare(); 
      mediaPlayer.start(); 
      prepared = true; 
     } catch (IOException e) { 
      e.printStackTrace(); 
      prepared = false; 
     } 

     return prepared; 
    } 

    @Override 
    protected void onPostExecute(Boolean aBoolean) { 
     super.onPostExecute(aBoolean); 

    } 
}