0

我添加了新接口,因为我可以在html中调用 android 方法。主要活动将html文件调用到我的webview和接口类以执行播放声音的播放方法。一切正常,但是当我添加代码以在关闭应用程序时停止声音或在按下返回键或主页键时关闭声音。但是当按下返回或主页键时也会出现错误“应用程序停止...... ”在旋转时发生。

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 的变量。因此,让我们重命名变量以更清楚。

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,因为它从来没有机会去!您的代码中的另一个问题是它缺少Encapsulation和基本的 OOP 概念。

所以在这里我将如何重写你的代码。

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) 方法使其停止或启动。

现在我注意到第三个潜在的错误。在你的活动中。

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,也可以更轻松地跟踪错误。


这个问题的原始信息:我注意到的另一件事是,在你的活动中,你有一个叫做

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 回答