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

标签 android google-cloud-messaging

我正在我的 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;
    }
}

Controller 在应用程序的 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();
}

现在,实际场景:应用程序在前台运行时一切正常。但是,如果我按“后退”退出关闭主要 Activity 并收到 GCM 消息,则可能会或可能不会发生崩溃。

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

最佳答案

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

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

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

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

关于android - 收到 GCM 消息时,静态对象并不总是存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32523447/

相关文章:

android - 下载phonegap中的资源包

android - BroadcastReceiver 收不到广播事件消息

android - 在 gradle 中设置 applicationId 以实现组合产品 flavor

IOS : Unable to setup GCM using cordova plugin phonegap-plugin-push

ios - 如何在 iOS 的应用程序内打开/关闭 GCM 推送通知的设置功能?

android - 如何发送高优先级 GCM?

android - Gradle同步错误Android Studio

java - Android:返回 Activity 时如何在EditText中保存值

android - 无法在 Android 中注销 GCM

android - 带有 AWS SNS 的 FCM