0

htmlで Android メソッドを呼び出すことができるため、新しいインターフェイスを追加しました。主なアクティビティは、私のwebviewとインターフェイス クラスにhtmlファイルを呼び出して、 play sound の play メソッドを実行します。すべてがうまくいきましたが、アプリを閉じるときに音を止めるか、戻るキーまたはホームキーを押すときに音を消すコードを追加したとき。しかし、回転時に戻るキーまたはホームキーを押すと、 「アプリケーションが停止しました... 」というエラーが発生しました。

public class x extends Activity {

private MediaPlayer mp;
private String TAG;
Context mContext;
private IntentListener listener = new IntentListener();
WebAppInterface wb= new WebAppInterface(mContext);

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);


    //Call HTML Files
    WebView myWebView = (WebView) findViewById(R.id.web_engine);

    WebSettings webSettings = myWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    myWebView.loadUrl("file:///android_asset/index.html");

    // Intiate interface

    myWebView.addJavascriptInterface(new WebAppInterface(this), "Android");


}
@Override
 protected void onPause()
 {
     super.onPause();
     if(mp.isPlaying())
     mp.pause(); //stop the sound
 }

 @Override
 protected void onResume() 
 {
     super.onResume();
     if(WebAppInterface.checked)
     {
         mp.start();
     }
 }
 @Override
 protected void onDestroy() 
 {
     super.onDestroy();
     if(WebAppInterface.checked)
     {
         mp.stop();
     }
 }

}

public class WebAppInterface    {
Context mContext;
 private MediaPlayer mp;
 public static boolean checked = false;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
    mContext = c;
}


@JavascriptInterface
public void playsound(String value  ) {
    if (value.equals("on")) {
        checked = true;
        mp= MediaPlayer.create(mContext,R.raw.sound);
        mp.setLooping(true);
        mp.start();
    }
    else 
    {  
        checked = false;
        mp.stop();
    }
}

}

 <activity
        android:name="com.ramadan.Ramadan"
        android:label="@string/app_name">

07-01 01:06:29.628: E/AndroidRuntime(631): java.lang.RuntimeException: Unable to pause activity {com.ramadan/com.ramadan.Ramadan}: java.lang.NullPointerException
4

2 に答える 2

1

編集バージョン 2: コメントから

mp is media player and it is initialized in interface , so can i initialize it on activity but from the interface 

その場合、コードの構造が正しくありません。mp という 2 つの変数があります。ですから、変数の名前をより明確にするために名前を変更しましょう。

private MediaPlayer mMediaPlayerActivity;  
private MediaPlayer mMediaPlayerWebApp;

インターフェイスで、mMediaPlayerWebApp をここで初期化します。

public void playsound(String value  ) {
    if (value.equals("on")) {
        checked = true;
        mMediaPlayerWebApp= MediaPlayer.create(mContext,R.raw.sound);
        mMediaPlayerWebApp.setLooping(true);
        mMediaPlayerWebApp.start();
    }
    else 
    {  
        checked = false;
        mMediaPlayerWebApp.stop();
    }
}

アクティビティでは、mMediaPlayerActivity をまったく初期化しません。しかし、onDestory/onPause イベントで使用しようとしています。コードを機能させるには、mMediaPlayerActivity をすべて削除し、mMediaPlayerWebApp を使用する必要があります。活動の中でそれをどのように行いますか?ここ

@Override
 protected void onDestroy() 
 {
     super.onDestroy();
     if(WebAppInterface.checked)
     {
         WebAppInterface.mMediaPlayerWebApp.stop(); //change mMediaPlayer to public
     }
 }

これで問題は解決しました。コードに別の潜在的な問題があることがわかります。playSound() が呼び出されない場合はどうなりますか? mMediaPlayerWebApp.stop() を呼び出そうとすると、別の nullpointerexception が発生します。コードのもう 1 つの問題は、基本的な OOP の概念であるEncapsulationがないことです。

ここで、コードをどのように書き直すかを説明します。

public class WebAppInterface 
{
    private MediaPlayer mMediaPlayerWebApp;
    private boolean mHasSoundPlaying = false;

    WebAppInterface(Context context) 
    {
        mMediaPlayerWebApp = MediaPlayer.create(context, R.raw.sound);
    }

    @JavascriptInterface
    public void playsound(String value) 
    {
        if (value.equals("on")) 
        {
            setSoundPlaying(true);
        } else 
        {
            setSoundPlaying(false);
        }
    }

    public void setSoundPlaying(Boolean isPlaying) 
    {
        this.mHasSoundPlaying = isPlaying;

        if (isPlaying) 
        {
            mMediaPlayerWebApp.setLooping(true);
            mMediaPlayerWebApp.start();
        }
        else
        {
            if (mMediaPlayerWebApp.isPlaying())
            {
                mMediaPlayerWebApp.stop();  
            }
        }
    }

public void pauseSound()
{
    this.mMediaPlayerWebApp.pause();
}


public Boolean getSoundPlaying()
{
    return this.mHasSoundPlaying;
}
}

次に、アクティビティで setSoundPlaying(boolean) メソッドを使用して停止または開始します。

ここで、3 つ目の潜在的なバグに気付きました。あなたの活動で。

WebAppInterface wb= new WebAppInterface(mContext);

mContext も初期化されません。これを次のように変更するだけです

WebAppInterface wb;

そして、OnCreate() で

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);


    //Call HTML Files
    WebView myWebView = (WebView) findViewById(R.id.web_engine);

    WebSettings webSettings = myWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    myWebView.loadUrl("file:///android_asset/index.html");

    // Instantiate interface

    this.wb = new WebAppInterface(this);

    myWebView.addJavascriptInterface(this.wb, "Android");
}

全体として、純粋なJavaの本をお勧めします。いくつかの基本的な OOP の概念を理解する必要があります。これらの概念は、コードが NullPointerException に陥るのを防ぐだけでなく、バ​​グの追跡を容易にします。


この質問に対する元のメッセージ: 私が気付くもう 1 つのことは、Activty に何かというものがあることです。

private MediaPlayer mp;

そしてさらに下にはこれがあります

 @Override
 protected void onDestroy() 
 {
     super.onDestroy();
     if(WebAppInterface.checked)
     {
         mp.stop();
     }
 }

アクティビティのどこにも MediaPlayer mp が初期化されている場所がありません。初期化するまで、メソッドを呼び出すことはできません。そうしないと、nullpointerexception が発生します。

于 2013-06-30T23:10:22.600 に答える
0

MediaPlayer mp初期化されていません。だから、あなたはNPEを取得します。

于 2013-07-01T09:21:39.390 に答える