Android 未调用静态对象的构造函数

Android ctor for static object not called

主要使用 Qt 和 QML 编写 android 应用程序,我正在尝试遵循 example for sending notifications。当我 运行 示例按预期工作时,但是当我将几乎相同的代码放入我的应用程序时,它不会为其中一个静态对象调用构造函数,因此失败。这是我的 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_instancenull,因为从未调用 NotificationClient 构造函数。

什么会导致这种情况发生?

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.

androidQt 应用程序是薄Java 层的复合体,在启动时调用打包为动态so 库的Qt 应用程序。可以在 Vatra 先生@ KDAB 举办的精彩系列的 first 博客 post 中找到更多详细信息。

Java 层恰好是主要 activity 加上一些实用程序 classes,在 Qt code base.

中可用

创建新的 Android 项目时,Qt Creator 会自动生成一个 manifest 文件,该文件使用 Qt 中可用的默认 classes。只要您使用默认设置,一切正常。

在你的情况下,你必须扩展默认的主 activity 来添加你的自定义 Java 代码,导致主 activity (NotificationClient) 的新名称。但是,清单指向(仍然)可用的基础 class 即您在清单中有:

android:name="org.qtproject.qt5.android.bindings.QtActivity"

在这种情况下,会调用 superclass 构造函数,因此未为 static 变量分配有效值,从而导致 nullPointerException 问题。在清单中设置正确的新主 activity 解决了问题:

android:name="com.me.myApp.NotificationClient"

我建议您仔细阅读上面链接的博客 posts 系列,因为它们可以轻松理解 Android Qt 项目中的 Java <--> C++ 交互。