按后退键并旋转时错误停止了应用程序

时间:2013-06-30 23:02:48

标签: android eclipse android-layout media-player

  

我添加了新界面,因为我可以在 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

2 个答案:

答案 0 :(得分: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,并且可以更轻松地跟踪错误。


此问题的原始讯息: 我注意到的另一件事是,在你的Activty中你有一个叫做

的东西
private MediaPlayer mp;

然后再下来你有这个

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

我没有看到MediaPlayer mp在您的活动中的任何位置初始化。在它初始化之前你不能调用任何方法,否则它会导致nullpointerexception。

答案 1 :(得分:0)

MediaPlayer mp未初始化。所以,你得到了NPE。