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
相关产品推荐
相关产品推荐

