Phonegap和C2DM - NullPointerException

时间:2012-02-07 13:07:01

标签: jquery-mobile cordova android-c2dm

我正在将C2DM与PhoneGap一起使用。当我收到C2DM消息时,我会显示通知(通过NotificationManager)。当用户选择通知时,我的应用程序会收到意图。在这种情况下,我想在我的jquery-mobile webapp中激活一个页面。

因此,我覆盖onNewIntent事件以存储意图:

@Override
protected void onNewIntent(final Intent intent)
{
    super.onNewIntent(intent);
    setIntent(intent);
}

然后,在onResume中,如果意图来自C2DM,我激活了正确的页面:

@Override
protected void onResume()
{
    super.onResume();

    // read possible argument
    boolean showMessage = getIntent().getBooleanExtra(ARG_SHOW_MESSAGES, false);
    if (showMessage)
    {
        clearNotification();
        super.loadUrl("file:///android_asset/www/de/index.html#messages");
    }
}

这样可以正常工作,但有时会出现NullPointerException崩溃 - 不是在我的手机或模拟器上,而是在其他设备上。 stacktrace表示它位于onNewIntent活动的DroidGap内,请参阅Code

protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    //Forward to plugins
    this.pluginManager.onNewIntent(intent);
}

我无法重现这种情况。显然pluginManager是null,但我不知道为什么。

所以问题是:

  • 采取的方法是从Android中选择jquery-mobile中的特定页面,还是有人指出更好的方法?
  • 如何摆脱异常?当然我可以检查pluginManager是否为null,在这种情况下不要调用super - 但是我的特定页面没有被激活。
  • 您认为这是一个PhoneGap错误 - 不是要检查pluginmanager是否为null?当我检查PhoneGap代码时,我认为这应该永远不会发生,我的理解onNewIntent仅在加载活动时被调用,否则将触发onCreate。

更新 我现在知道的更多:当没有加载应用程序并且C2DM消息到达时出现问题。 意图启动应用程序,事件按以下顺序发生 - 但onNewIntent仅偶尔调用:

onCreate()
onNewIntent()
onResume()

每当在启动期间执行onNewIntent时它就会崩溃。无论如何,我修复了这个:

@Override
protected void onNewIntent(final Intent intent)
{
    // avoid Phonegap bug
    if (pluginManager != null)
    {
        super.onNewIntent(intent);
    }
    setIntent(intent);
}

当我想更改onResume-Event中的起始页面时,当Phonegap未准备就绪时,这不起作用。因此,在应用程序启动的情况下,只需尽早调用onResume中的#messages页面即可。但什么时候打电话呢?是否有可能挂钩onDeviceReady?

1 个答案:

答案 0 :(得分:1)

我仍然不知道为什么有时onNewIntent会在应用程序启动期间触发(不仅仅是激活),有时也不会。无论如何,我通过一些解决方法解决了所有问题。

在我的活动中,我创建了一个新功能(不相关的部分被剥离):

public void onDeviceReady()
{
    if (!isReady)
    {
        super.loadUrl("file:///android_asset/www/en/index.html#messages");
    }

    // activate onResume instead
    isReady = true;
}

和上面的布尔标志:

/** Is PhoneGap ready? */
private boolean isReady = false;

我在onCreate事件中激活回调:

// Callback setzen
appView.addJavascriptInterface(this, "Android");

并从Javascript onDeviceReady

调用它
if (OSName == "Android")
{
    window.Android.onDeviceReady();
}

在onResume事件中,我使用协商逻辑:

protected void onResume()
{
    super.onResume();

    if (isReady)
    {
        super.loadUrl("file:///android_asset/www/en/index.html#messages");
    }
}

这可以保证页面选择只在onResume或onDeviceReady中执行一次。