收到 GCM 消息时,静态对象并不总是存在

Static objects are not always there when a GCM message is received

我正在我的 Android 应用程序中实施 GCM。到目前为止一切顺利,消息传递有效,但是当收到消息时,应用程序可能会或可能不会崩溃 NullPointerException。发生这种情况的原因是因为静态引用有时是 null 有时不是,但我不知道发生这种情况的原因。

可能为 null 也可能不为 null 的对象是 MessageController 通过简单的服务定位器模式定位的对象,如下所示:

public class ControllerLocator
{
    private static MessageController controller; 

    public static MessageController getMessageController()
    {
        return controller;
    }

    public static void provide(MessageController mc)
    {
        controller = mc;
    }
}

控制器在应用程序的onCreate()方法中设置:

@Override
public void onCreate()
{
    super.onCreate();
    ControllerLocator.provide(new MessageController());
}

// Later on in the program after backend authentication:
ControllerLocator.getMessageController().setCredentials(...);

GCM 消息处理是这样的:

@Override
protected void onHandleIntent(Intent intent)
{
    Bundle extras = intent.getExtras();
    String msgType = GoogleCloudMessaging.getInstance(this).getMessageType(intent);
    if(msgType.equals(GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE))
    {
        handleMessage(extras.getString("message"));
    }

    GcmBroadcastReceiver.completeWakefulIntent(intent);
}

private void handleMessage(String msg)
{
    // 'controller' may or may not be null
    MessageController controller = ControllerLocator.getMessageController();
}

现在,实际情况:当应用程序在前台 运行 时一切正常。但是,如果我按 "back" 退出关闭主 activity 并收到 GCM 消息,则可能会或可能不会发生崩溃。

为什么删除了静态引用?我该如何解决这个问题以确保控制器始终存在?

这是因为在您等待 GCM 消息时,您的应用程序进程已被终止,并且它持有的所有内存都已释放。 当您的 GCM 消息传入时,系统会再次创建您的应用程序进程和应用程序对象,因此您得到了 null。

只需在您的 get 实例方法中检查该实例是否为 null,如果它为 null,则重新创建您的对象。

编辑: 无法确保同一个对象始终处于活动状态,Android 系统一次有 运行 个应用程序并且不能允许任何应用程序填满内存,因此它可能会在其他应用程序需要时终止您的进程内存,这将自动释放您保留的内存,包括静态变量。作为 Android 开发人员,您的工作就是处理它:)

为了避免重新授权和大量的娱乐计算,您可能需要重新考虑您的设计,以便对象的状态是持久的,也许可以使用 SharedPreferences。

将您的 MessageController 变量设为静态。

您无法确保您的静态控制器对象将处于活动状态(不为空),因为后台应用程序是 GC 的理想候选对象。

但是,您可以在收到 GCM 消息数据时将其保存在 SQLite 中。然后在打开应用程序时检查 table 中的数据。