未调用静态对象的Android ctor
Posted
技术标签:
【中文标题】未调用静态对象的Android ctor【英文标题】:Android ctor for static object not called 【发布时间】:2016-12-26 16:39:41 【问题描述】:主要使用 Qt 和 QML 编写一个 android 应用程序,我正在尝试遵循 example for sending notifications。当我运行示例时,事情按预期工作,但是当我将几乎相同的代码放入我的应用程序时,它不会为其中一个静态对象调用 ctor,因此事情会失败。这是我的 Java 代码:
package com.me.myApp;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.util.Log;
public class NotificationClient extends org.qtproject.qt5.android.bindings.QtActivity
private static final String TAG = "myApp::NotificationClient";
private static NotificationManager m_notificationManager;
private static Notification.Builder m_builder;
private static NotificationClient m_instance;
public NotificationClient()
Log.d(TAG, "Doing ctor");
m_instance = this;
public static void notify(String s)
Log.d(TAG, "Doing the update thing");
if(m_instance == null)
Log.d(TAG, "I have a null instance");
try
if (m_notificationManager == null)
m_notificationManager = (NotificationManager)m_instance.getSystemService(Context.NOTIFICATION_SERVICE);
m_builder = new Notification.Builder(m_instance);
// m_builder.setSmallIcon(R.drawable.icon);
m_builder.setContentTitle("A message from Qt!");
m_builder.setContentText(s);
m_notificationManager.notify(1, m_builder.build());
catch (Exception ex)
Log.d(TAG, "Notify error: " + ex.toString());
查看日志文件,它进入了notify()
函数,但m_instance
是null
,因为从未调用过NotificationClient
ctor。
什么会导致这种情况发生?
【问题讨论】:
【参考方案1】:Android Qt 应用程序是一个薄 Java 层的组合,它在启动时调用打包为动态 so
库的 Qt 应用程序。更多详细信息可以在 Vatra 先生 @KDAB 举办的精彩系列文章的 first 博客文章中找到。
Java 层恰好是主要活动以及一些实用程序类,可在Qt code base 中找到。
当创建一个新的 Android 项目时,Qt Creator 会自动生成一个manifest
文件,该文件使用 Qt 中可用的默认类。只要您使用默认设置,一切正常。
在您的情况下,您必须扩展默认的主要活动以添加您的自定义
Java 代码,导致主要活动的新名称 (NotificationClient
)。然而,清单指向(仍然)可用的基类,即您的清单中有:
android:name="org.qtproject.qt5.android.bindings.QtActivity"
在这种情况下,超类 ctor 被调用,因此 static
变量未分配有效值,从而导致 nullPointerException
问题。在清单中设置正确的新主要活动可以解决问题:
android:name="com.me.myApp.NotificationClient"
我建议您仔细阅读上面链接的博客文章系列,因为它们可以轻松理解 Android Qt 项目中的 Java C++ 交互。
【讨论】:
【参考方案2】:m_instance
(不遵循 Java 命名约定)仅在 NotificationClient
构造函数中初始化,但它是 static
成员。除此之外,这意味着每个实例初始化都会不可预测地改变该值,构造函数永远不会在您的代码中实际调用。一个类型的静态成员不会神奇地调用它的构造函数;它只有在代码要求时才会被构造。
您永远不应该假设某事会以某种方式发生,您应该通过研究文档知道会发生什么。 https://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
如果没有显式初始化,成员值将保持其默认值;对于您的NotificationClient
成员,该值为null
。
【讨论】:
我的代码几乎一字不差地取自 qt 示例。再次查看他们的示例,我没有看到 java NotificationClient 对象的任何显式初始化。根据您的描述,示例编写不正确,它的工作原理只是一个意外?以上是关于未调用静态对象的Android ctor的主要内容,如果未能解决你的问题,请参考以下文章