getApplication() 和跨给定应用程序内的活动

发布于 2024-12-10 08:48:57 字数 966 浏览 1 评论 0原文

我花了一段时间阅读此内容,但尚未找到答案。

我在一个应用程序中进行了一些活动。我想在它们之间共享一些不适合意图或序列化数据文件的数据。我知道我可以使用整个应用程序来实现此目的,但我不完全理解它是如何工作的。

我们将我的整个应用程序类称为“MyApplication”,将主要活动称为“MyActivity”。我希望应用程序从冷启动开始后,它首先实例化并初始化 MyApplication (调用 onCreate()),然后继续实例化并启动我的活动 (MyActivity) (其标记为意图 android.intent.action 。主要的)。日志似乎证实了这一点。

但是...如果我尝试设置以下活动范围的变量,它会被设置为 null: 私人最终MyApplication THISAPP = (MyApplication)getApplication();

这很奇怪,因为应用程序此时肯定存在。 (另外,我不能延迟设置最终变量,直到调用 MyActivity.onCreate() 为止 - 这是不允许的(“最终字段......无法分配”))。

请注意,如果我不将 THISAPP 称为“最终”并在 onCreate() 中分配它,则此方法有效。这当然违背了用“final”保护变量的目的,而且看起来应该是可以做到的。

那么,为什么 getApplication() 在 onCreate() 之前没有生成非空值?或者这是上下文的一些奇怪问题?(我发现对上下文的模糊引用在 onCreate() 完成后才有效,但这是否适用于从子 Activity 中看到的父应用程序的上下文?我希望父母此时已经设置了该设置。)

编辑:强调一下,如果我不尝试使用 Final 并且记得添加“.”,我就可以让它工作。在清单中的应用程序名称之前(我在写此问题之前犯过并纠正了错误)。只是不清楚为什么 getApplication() (或 getApplicationContext() )在子 Activity 中的 onCreate() 之前不可用......除非“就是这样”。

I've spent a while reading up on this and have yet to find an answer.

I have a few activities all within one app. I'd like to share some data between them that is not suitable for intents or serialized data files. I know I can use the overall Application for this purpose, but I'm not fully understanding how it works.

We'll call my overall application class "MyApplication" and the main activity "MyActivity". I would expect that once the app begins from a cold start, it first instantiates and initializes MyApplication (calling onCreate()) and then goes on to instantiate and start my activity (MyActivity) (which was marked with the intent android.intent.action.MAIN). The logs seem to bear this out.

But... if I try to set the following Activity-wide variable, it gets set to null:
private final MyApplication THISAPP = (MyApplication)getApplication();

This is peculiar because the application definitely exists at this point. (Also, I can't delay setting a final variable til MyActivity.onCreate() gets called - that's disallowed ("The final field...cannot be assigned")).

Note that this works if I don't call THISAPP "final" and I assign it in onCreate(). That of course defeats the purpose of protecting a variable with "final" though, and it seems like it should be possible to do.

So, why isn't getApplication() producing a non-null value before onCreate()? Or is this some strange matter of context? (I've found a vague reference to context not being valid til after onCreate() is done, but would that apply to the parent Application's context as seen from a child Activity? I'd expect the parent to already have that set at that point.)

Edit: to emphasize, I can get this to work if I don't try to use final and if I remember to put the "." before the application name in the manifest (a mistake I made and corrected well-before this I wrote this question). It just isn't clear why getApplication() (or getApplicationContext() for that matter) aren't usable before onCreate() in a child Activity... unless "that's just how it is".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

┈┾☆殇 2024-12-17 08:48:57

我想在它们之间共享一些不适合意图或序列化数据文件的数据。我知道我可以使用整个应用程序来实现此目的,但我并不完全理解它是如何工作的。

我只是使用静态数据成员作为持久存储的缓存,而不是在 Application 上大惊小怪。 Application 与静态数据成员相比几乎没有什么优势,并且有一个很大的成本:只能有一个 Application,而您可以根据自己的喜好组织静态数据成员/单例。

我希望应用程序从冷启动开始后,它首先实例化并初始化 MyApplication(调用 onCreate()),然后继续实例化并启动我的 Activity (MyActivity)(其标记有意图 android.Activity)。意图.动作.MAIN)。日志似乎证实了这一点。

正确的。

但是...如果我尝试设置以下活动范围变量,它会设置为 null: private Final MyApplication THISAPP = (MyApplication)getApplication();

当然。活动对象尚未初始化。欢迎您对常量或从静态方法(例如,Calendar.getInstance())或其他构造函数(例如,new ArrayList()< /代码>)。不要调用超类方法并期望它在此时起作用,因为尚未在正在实例化的对象上调用构造函数链。这只是 Java,对于 Android 来说没有什么特别的。

I'd like to share some data between them that is not suitable for intents or serialized data files. I know I can use the overall Application for this purpose, but I'm not fully understanding how it works.

I'd just use static data members as a cache for your persistent store, rather than fussing around with Application. Application gives you little advantage over static data members and has one big cost: there can only be one Application, whereas you can organize your static data members/singletons however you like.

I would expect that once the app begins from a cold start, it first instantiates and initializes MyApplication (calling onCreate()) and then goes on to instantiate and start my activity (MyActivity) (which was marked with the intent android.intent.action.MAIN). The logs seem to bear this out.

Correct.

But... if I try to set the following Activity-wide variable, it gets set to null: private final MyApplication THISAPP = (MyApplication)getApplication();

Of course. The activity object has not yet been initialized. You are welcome to use initializers like this for constants or things you get from static methods (e.g., Calendar.getInstance()) or other constructors (e.g., new ArrayList<Foo>()). Do not call a superclass method an expect it to work at this point, since the constructor chain has not yet been called on the object being instantiated. This is just Java, nothing particular to Android.

妞丶爷亲个 2024-12-17 08:48:57

你有按照下面的方法做过吗?

创建了一个实现应用程序定义的类

public class MySuperApplication extends Application 
{ 
    public String SomeSetting; 
}

,它是清单中的应用程序类(重要!)

<application android:name=".MySuperApplication" android:icon="@drawable/icon"

,然后在您的活动中访问它

app = (MySuperApplication) getApplication();
app.SomeSetting = "Test";

这应该可以工作。就我而言确实如此。

Have you done it the following way?

Created a class that implements Application

public class MySuperApplication extends Application 
{ 
    public String SomeSetting; 
}

Defined which is your Application class in manifest (important!)

<application android:name=".MySuperApplication" android:icon="@drawable/icon"

and then accessed it in your activities

app = (MySuperApplication) getApplication();
app.SomeSetting = "Test";

This should work. It does in my case.

吃素的狼 2024-12-17 08:48:57

AFAIK,您不能声明一个空的 final 变量并在 Create 时对其进行初始化。在java中,它是在声明变量或构造函数中初始化的。

THISAPP 在声明期间无法初始化为 Application 对象,因为 Application 在编译时不存在。由于 onCreate 不是构造函数,因此您无法声明空的 final 变量并在 onCreate 中对其进行初始化。

AFAIK, You cannot declare a empty final variable and initialize it onCreate. In java it is initialized during declaring the variable or in the constructor.

THISAPP cannot be initialized to Application object during declaration because the Application doesn't exist during compile time. Because onCreate is not a constructor, you cannot declare a empty final variable and initialize it in onCreate.

谁的年少不轻狂 2024-12-17 08:48:57

实例变量是在构造对象(在本例中为 Activity 对象)时创建的。为了使 getApplication() 产生有效值,必须在实例化时为 Activity 对象提供足够的上下文(小“c”)才能发生这种情况。

Activity.java 中 getApplication() 的源代码如下:

/** Return the application that owns this activity. */
public final Application getApplication() {
    return mApplication;
}

这是它的设置位置:

final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token,
        Application application, Intent intent, ActivityInfo info, CharSequence title, 
        Activity parent, String id, Object lastNonConfigurationInstance,
        Configuration config) {
    // other code
    mApplication = application;
    // other code
}

由于 mApplication 在调用 Attach 后才设置,因此在实例化 Activity 时 getApplication() 无法使用它。

Instance variables are created when the object (in this case an Activity object) is constructed. For getApplication() to produce a valid value then the Activity object would have to have been provided enough context (little 'c') at instantiation for this to occur.

The source for getApplication() in Activity.java is just this:

/** Return the application that owns this activity. */
public final Application getApplication() {
    return mApplication;
}

Here is where it is set:

final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token,
        Application application, Intent intent, ActivityInfo info, CharSequence title, 
        Activity parent, String id, Object lastNonConfigurationInstance,
        Configuration config) {
    // other code
    mApplication = application;
    // other code
}

Since mApplication is not set until after attach is called, it won't be available to getApplication() on instantiation of your Activity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文