2017-06-17 8 views
0

こんにちは私は音楽ストリーミングのための反応ネイティブアンドロイドモジュールを構築しています。音楽をストリーミングしようとすると、読み込んだ最初のURLで動作しますが、別のURLを読み込もうとするとアプリがクラッシュします。Android music streamer

モジュールのコードは次のとおりです。

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で2番目のページに移動します。ここでは、2ページ目(曲を果たしているページ)のための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

は、私はブール= falseを用意しlogcat – digiwebguy

+0

」を追加しました。 "この行を "doInBackground()"から削除してください。 「準備」は常に「偽」のままであるため、メディアプレーヤーは「公開無効再生(String url)」としてリセットすることはできません。上記の行を削除すると、グローバルな "準備"に直接アクセスできます。 –

+0

ありがとうございます。どのように私はそれを逃したのか分からない。私はそれを削除しましたが、それでもまだクラッシュします:/ – digiwebguy

0

@Rahul Guptaのコメントは、正しい方法で問題について考えさせてくれました。だから問題は私が間違った場所に準備のためのチェックをしていたということでした。私がする必要があったのは、if(prepared)elseブロックを私の非同期タスクに移動して問題を解決することでした。ここでは、コードです:

これはプレイ方法は、今のように見えるものです:

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

、ここでは、ASYNCタスクです:

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); 

    } 
} 
関連する問題