为什么要扩展 Android 应用程序类?

扩展的 Application类可以声明全局变量。还有其他原因吗?

136000 次浏览

应用程序类是具有应用程序整个生命周期的对象。它是应用程序的最高层。例子可能的用法:

  • 通过在 Application 类中重写 onCreate,可以在启动应用程序时添加所需的内容。

  • 存储从 Activity 跳转到 Activity 的全局变量。

    等等

Application 类是一个单例模式,您可以从任何活动或任何拥有 Context 对象的地方访问它。

还有一些生命周期。

您可以使用 Application 的 onCreate 方法来实例化昂贵但经常使用的对象,比如分析帮助器。然后您就可以在任何地方访问和使用这些对象。

一下子,我想不出一个真正的场景,在这个场景中,扩展 Application 要么优于另一种方法,要么是完成某些事情所必需的。如果您有一个昂贵的、经常使用的对象,那么当您检测到该对象当前不存在时,您可以在 InentService 中对其进行初始化。应用程序本身在 UI 线程上运行,而 InentService 在自己的线程上运行。

我更喜欢用显式的意图将数据从 Activity 传递到 Activity,或者使用 SharedPreferences。还有一些方法可以使用接口将数据从片段传递给其父活动。

您可以访问任何类的变量,而不需要创建对象(如果由 Application 扩展的话)。它们可以被全局调用,并且它们的状态一直保持到应用程序没有被终止。

有时候您想要存储数据,比如需要从多个 Activity 访问的全局变量——有时候是应用程序中的任何地方。在这种情况下,Application 对象将帮助您。

例如,如果希望获得每个 译注:请求的基本身份验证数据,可以在应用程序对象中实现身份验证数据的方法。

在此之后,您可以获得用户名和密码的任何活动,如下所示:

MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();

最后,请记住使用 Application 对象作为单例对象:

public class MyApplication extends Application {
private static MyApplication singleton;


public MyApplication getInstance(){
return singleton;
}


@Override
public void onCreate() {
super.onCreate();
singleton = this;
}
}

有关详细资料,请按 申请类别

这不是一个答案,而是 观察: 请记住,扩展应用程序对象中的数据不应该绑定到活动的实例,如 可能有两个同一活动的实例同时运行(一个在前台,一个不可见)

例如,您通过启动程序正常地开始您的活动,然后“最小化”它。然后启动另一个应用程序(即 Tasker) ,它会启动您活动的另一个实例,例如为了创建快捷方式,因为您的应用程序支持 android.intent.action.CREATE _ SHORTCUT。如果创建了快捷方式,并且这个创建快捷方式的活动调用修改了应用程序对象的数据,那么在后台运行的活动将在这个修改后的应用程序对象被带回前台后开始使用它。

扩展应用程序的使用只是确保应用程序在整个应用程序运行期间可以执行任何类型的操作。现在它可能是任何类型的变量,假设如果你想从服务器获取一些数据,那么你可以把你的异步任务放在应用程序中,这样它就会每次连续获取,这样你就会自动获得一个更新的数据。.使用这个链接获得更多的知识... 。

Http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android

简介:

enter image description here

  1. 如果我们考虑一个 apk文件在我们的手机,它是由 多个有用的块,如 ActivityService和 其他人。
  2. 这些组件之间不能定期通信,而且 不要忘记他们有自己的生命周期。这表明 他们可能在一个时刻是活跃的,而在另一个时刻是不活跃的。

要求:

  1. 有时我们可能需要一个场景,其中需要访问 变量及其在整个 Application中的状态 用户正在使用的 Activity,
  2. 一个例子是,用户可能需要访问一个保存他的 人事资料(例如姓名) Application,
  3. 我们可以使用 SQLite,但是要创建一个 Cursor并再次关闭它 再次表现不佳,
  4. 我们可以使用 Intent来传递数据,但是它很笨拙,而且很活跃 根据内存可用性的不同,它本身可能不存在于某个场景中。

申请类别用途:

  1. 通过 Application访问变量,
  2. 您可以使用 Application来开始某些事情,比如分析 等,因为应用程序类是在 ActivityServices正在运行,
  3. 有一个名为 onConfigurationChanged ()的重写方法,即 当应用程序配置更改时触发(水平 直立及反之亦然) ,
  4. 还有一个名为 onLowMemory ()的事件,当 Android 设备内存不足。

应用程序类的最佳使用。 示例: 假设您需要在启动完成后重新启动闹钟管理器。

public class BaseJuiceApplication extends Application implements BootListener {


public static BaseJuiceApplication instance = null;


public static Context getInstance() {
if (null == instance) {
instance = new BaseJuiceApplication();
}
return instance;
}


@Override
public void onCreate() {
super.onCreate();




}


@Override
public void onBootCompleted(Context context, Intent intent) {
new PushService().scheduleService(getInstance());
//startToNotify(context);
}

我认为您可以使用应用程序类做很多事情,但是它们都与您在开始任何活动或服务之前需要做一些事情有关。 例如,在我的应用程序中,我使用自定义字体

Typeface.createFromAsset()

从每个 Activity 中获取我的字体的引用(这很糟糕,因为它会导致内存泄漏,因为你每次调用那个方法时都会保留对资产的引用) ,我在 Application 类中使用 onCreate()方法:

private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
super.onCreate();


appInstance = this;
quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
"fonts/Quicksand-Regular.otf");
...
}

现在,我还有一个这样定义的方法:

public static App getAppInstance() {
return appInstance;
}

还有这个:

public Typeface getQuickSandRegular() {
return quicksandRegular;
}

因此,在我的应用程序的任何地方,我所要做的就是:

App.getAppInstance().getQuickSandRegular()

对于我来说,Application 类的另一个用途是在需要连接的活动和服务实际启动并采取必要行动之前检查设备是否连接到 Internet。

我发现这个问题缺少一个答案。我扩展 Application是因为我使用 Bill Pugh 辛格尔顿实现(见参考文献) ,而且我的一些单例需要上下文。Application类是这样的:

public class MyApplication extends Application {


private static final String TAG = MyApplication.class.getSimpleName();


private static MyApplication sInstance;


@Contract(pure = true)
@Nullable
public static Context getAppContext() {
return sInstance;
}


@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() called");
sInstance = this;
}
}

这些单身人士看起来是这样的:

public class DataManager {


private static final String TAG = DataManager.class.getSimpleName();


@Contract(pure = true)
public static DataManager getInstance() {
return InstanceHolder.INSTANCE;
}


private DataManager() {
doStuffRequiringContext(MyApplication.getAppContext());
}


private static final class InstanceHolder {
@SuppressLint("StaticFieldLeak")
private static final DataManager INSTANCE = new DataManager();
}
}

通过这种方式,我不需要每次使用单例模式时都有上下文,也不需要用最少的代码进行延迟同步初始化。

提示: 更新 Android Studio 单例模板可以节省很多时间。

资料来源: https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class

在许多应用程序中,不需要直接使用应用程序类。但是,自定义应用程序类有一些可以接受的用法:

  • 在创建第一个活动之前需要运行的专门任务
  • 需要在所有组件之间共享的全局初始化(崩溃报告、持久性)
  • 易于访问静态不可变数据(如共享网络客户端对象)的静态方法

永远不应该在 Application 对象中存储可变的实例数据,因为如果假定数据将停留在那里,那么应用程序将不可避免地在某个时刻发生 NullPointerException 崩溃。应用程序对象不能保证永远留在内存中,它会被杀死。与流行的看法相反,这个应用程序不会从头开始重新启动。Android 将创建一个新的 Application 对象,并在用户之前所在的位置启动活动,从而给人一种应用程序从未被杀死的错觉。

添加到其他答案中,声明您可能希望在应用程序作用域中存储变量,用于任何需要绑定到您的应用程序的长时间运行的线程或其他对象,而您不使用活动(应用程序不是活动)。.例如无法请求绑定服务。.然后绑定到应用程序实例是首选的。这种方法唯一明显的警告是,只要应用程序存在,对象就会存在,因此需要对内存进行更多的隐式控制,否则就会遇到与内存相关的问题,比如泄漏。

您可能会发现其他有用的地方是,按照操作的顺序,应用程序在任何活动之前首先启动。在这个时间范围内,如果你愿意的话,你可以在第一次活动之前准备任何必要的家务活。

2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created