You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java类中获取Kotlin编写的Application类Context报空指针如何解决

问题根因

你不能手动实例化App类,Android的Application组件是由系统框架在应用启动时自动创建、绑定上下文并管理生命周期的,手动new App()得到的实例没有经过系统初始化流程,内部的Context本身就是空值,调用getApplicationContext()自然触发空指针异常。
另外你原有代码的单例实现存在错误:空实例判断后没有给静态instance赋值,会导致每次调用都创建新的实例,后续方案中也会同步修复该问题。

修复方案

方案1:全局Application实例持有(适配你当前的Dagger2架构)

第一步:修改自定义App类

添加静态实例持有,同时在Manifest中注册该App类:

class App : DaggerApplication() {
    companion object {
        @JvmStatic // 添加该注解后Java代码可直接调用App.getInstance()获取实例
        lateinit var instance: App
            private set
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
    }

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.factory().create(this)
    }
}

同时必须在AndroidManifest.xml的<application>节点添加配置,系统才会使用你自定义的App类:

<application
    android:name=".App"
    <!-- 其他配置不变 -->
    >

第二步:修改NotificationUtil工具类

直接调用App的全局实例获取Context:

public class NotificationUtil {
    private static NotificationUtil instance;

    private NotificationUtil() {
    }

    public static synchronized NotificationUtil getInstance() {
        if (instance == null)
            // 修复原有单例错误,给静态instance赋值
            instance = new NotificationUtil();
        return instance;
    }

    public void postNotificationSpam(StatusBarNotification sbn, int numberNotify) {
        // 直接使用全局Application实例,Application本身就是Context,也可以调用getApplicationContext()
        Context context = App.getInstance();
        NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        // 剩余业务逻辑不变
    }
}

方案2:调用时传入Context(无依赖耦合,更安全)

如果你不想让工具类依赖自定义App类,可以修改方法签名要求调用方传入Context,优先取ApplicationContext避免内存泄漏:

修改NotificationUtil方法

public void postNotificationSpam(Context context, StatusBarNotification sbn, int numberNotify) {
    // 统一取ApplicationContext避免持有Activity实例导致内存泄漏
    Context appContext = context.getApplicationContext();
    NotificationManager nm = (NotificationManager) appContext.getSystemService(Context.NOTIFICATION_SERVICE);
    // 剩余业务逻辑不变
}

调用处修改

在Activity中调用时传入Context即可:

NotificationUtil.getInstance().postNotificationSpam(this, lstNotify.get(0).barNotification, lstNotify.size());
注意事项
  • 不要手动实例化Android四大组件(Activity、Service、Application、ContentProvider、BroadcastReceiver),这类组件都由系统负责创建和生命周期管理,手动new的实例不具备任何组件功能
  • 工具类使用Context优先取ApplicationContext,避免持有Activity实例导致的内存泄漏

内容的提问来源于stack exchange,提问作者Armenak Mkhitaryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:24:07