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