简体   繁体   English

如何从“扩展应用程序”类创建意图,上下文为空

[英]How to create an intent from an “extends Application” class, context is null

I have a class which extends android.app.Application , which I use to persist global state around my application. 我有一个扩展android.app.Application的类,该类用于在应用程序周围保持全局状态。

I want to start off a service when my application starts, so inside the constructor of this GlobalState class I try to create an intent and start a service, but I can't create an intent because I can't get hold of Context 我想在应用程序启动时启动服务,所以在此GlobalState类的构造函数中,我尝试创建一个意图并启动一个服务,但是由于无法获取Context ,所以我无法创建意图。

public GlobalState() {
    Log.d(this.getClass().getSimpleName(), "Initialise DatabaseManager");
    dbManager = new DatabaseManager(this);

    Log.d(this.getClass().getSimpleName(), "Requesting start up of ContactsUpdater Service");
    Intent i = new Intent(this, ContactsUpdater.class);
    startService(i);
}

I've tried using getApplicationContext() , but this throws a null pointer exception. 我尝试使用getApplicationContext() ,但这会引发空指针异常。

java.lang.NullPointerException at android.content.ContextWrapper.getPackageName(ContextWrapper.java:120) at android.content.ComponentName.(ComponentName.java:75) at android.content.Intent.(Intent.java:2551) at com.jameselsey.apps.cercademi.domain.GlobalState.(GlobalState.java:48) at java.lang.Class.newInstanceImpl(Native Method) at java.lang.Class.newInstance(Class.java:1479) at android.app.Instrumentation.newApplication(Instrumentation.java:957) at android.app.Instrumentation.newApplication(Instrumentation.java:942) at android.app.ActivityThread$PackageInfo.makeApplication(ActivityThread.java:518) com.android.content.Intent。(Intent.java:2551)处android.content.ComponentName。(ComponentName.java:75)处android.content.ContextWrapper.getPackageName(ContextWrapper.java:120)处的java.lang.NullPointerException .jameselsey.apps.cercademi.domain.GlobalState。(GlobalState.java:48)在java.lang.Class.newInstanceImpl(本机方法)在java.lang.Class.newInstance(Class.java:1479)在android.app。 android.app.Instrumentation.newApplication(Instrumentation.java:942)的Instrumentation.newApplication(Instrumentation.java:957)android.app.ActivityThread $ PackageInfo.makeApplication(ActivityThread.java:518)

I'm confused, I can create the DatabaseManager fine using this.. 我很困惑,我可以使用它来创建DatabaseManager

Any ideas? 有任何想法吗?

For Activity, Service, ContentProvider and Application, you should not do anything in the constructor. 对于Activity,Service,ContentProvider和Application,您不应在构造函数中执行任何操作。 The first place you should do work, when you know the object is initialized and ready for use, is onCreate(). 当您知道对象已初始化并可以使用时,应该做的第一个工作是onCreate()。

Further, please think again about "I want to start off a service when my application starts." 此外,请再次考虑“我想在我的应用程序启动时启动服务”。 What you code is doing here is trying to start a service when your process happens to start. 您的代码在这里执行的操作是试图在您的进程恰好启动时启动服务。 I really don't think you want that. 我真的不想要你。 You want this service to start because you happened to receive a broadcast in the background? 您要启动此服务,因为您碰巧在后台收到广播吗?

If you just want to do some first time init, my recommendation is to not use Application at all. 如果您只是想进行一些首次init,我的建议是完全不使用Application。 Have a singleton that can be retrieved when it is needed. 有一个单例可以在需要时进行检索。 Then your init happens at the point it is actually needed. 然后,您的初始化会在实际需要的时候发生。 There is no need for this to be associated with a service; 无需将此与服务关联; you can just make a thread. 你可以做一个线程。 The only reason to use a Service is to tell the system "my app is busy doing background work that the user cares about, please try not to kill me." 使用服务的唯一原因是告诉系统“我的应用正在忙于用户关心的后台工作,请不要杀死我。”

Base class for those who need to maintain global application state. 需要维护全局应用程序状态的人员的基类。 You can provide your own implementation by specifying its name in your AndroidManifest.xml's <application> tag , which will cause that class to be instantiated for you when the process for your application/package is created. 您可以通过在AndroidManifest.xml的<application>标记中指定其名称来提供自己的实现,这将在创建应用程序/包的过程时为您实例化该类。

Source: http://developer.android.com/reference/android/app/Application.html 来源: http//developer.android.com/reference/android/app/Application.html

Four times out of ten, an Android developer's force close problem is forgetting to modify the Android manifest. 十分之四的Android开发人员的强制关闭问题忘记了修改Android清单。 (I totally made up that statistic). (我完全弥补了该统计数据)。

Application extends Context , so you should be able to pass it. Application扩展了Context ,因此您应该能够传递它。

However, extending Application is not the most resource-efficient way of doing this. 但是,扩展应用程序不是执行此操作最节省资源的方法。 To explain it more succinctly, here's a nother quote from the same page: 为了更简洁地解释它,这是同一页上的另一句名言:

There is normally no need to subclass Application. 通常不需要子类化Application。 In most situation, static singletons can provide the same functionality in a more modular way. 在大多数情况下,静态单例可以以更模块化的方式提供相同的功能。 If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton. 如果您的单身人士需要全局上下文(例如,注册广播接收者),则可以在首次构造单身人士时为该函数提供一个上下文,该上下文在内部使用Context.getApplicationContext()。

确保在onCreate()调用super.onCreate()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM