为什么要扩展Application类?

时间:2013-08-01 18:53:25

标签: android android-application-class

为什么要延长Application课程?

它对我有什么用?

你为什么这样做?

我读过它可以用来声明全局变量,是全部还是其他任何应用程序?

13 个答案:

答案 0 :(得分:113)

简介:

enter image description here

  1. 如果我们在移动设备中考虑apk文件,则由...组成 多个有用的块,例如Activity s,Service和 他人。
  2. 这些组件不会定期相互通信 不要忘记他们有自己的生命周期。这表明 他们可能一次活跃而另一个时刻不活跃。
  3. 要求:

    1. 有时我们可能需要一个我们需要访问的场景 变量及其在整个Application中的状态,无论如何 用户正在使用的Activity
    2. 一个例子是用户可能需要访问保存他的变量 必须通过网站访问的人事信息(例如姓名) Application
    3. 我们可以使用SQLite但创建Cursor并再次关闭它 再次表现不佳,
    4. 我们可以使用Intent来传递数据,但这是笨拙的活动 根据内存可用性,在某种情况下可能不存在。
    5. 应用程序类的使用:

      1. 访问Application
      2. 中的变量
      3. 您可以使用Application启动分析等特定内容 因为应用程序类是在Activity之前启动的 正在运行Services
      4. 有一个名为onConfigurationChanged()的重写方法 更改应用程序配置时触发(水平 垂直和反之亦然),
      5. 还有一个名为onLowMemory()的事件在被触发时被触发 Android设备的内存不足。

答案 1 :(得分:62)

应用程序类是具有应用程序完整生命周期的对象。它是您作为应用程序的最高层。示例可能的用法:

  • 您可以通过覆盖Application类中的onCreate来添加启动应用程序时所需的内容。
  • 存储从Activity跳转到Activity的全局变量。像Asynctask一样。

答案 2 :(得分:30)

有时您希望存储数据,例如需要从多个活动访问的全局变量 - 有时在应用程序中的任何位置。在这种情况下,Application对象将为您提供帮助。

例如,如果要获取每个 http 请求的基本身份验证数据,可以在应用程序对象中实现身份验证数据的方法。

在此之后,您可以在以下任何活动中获取用户名和密码:

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

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

 public class MyApplication extends Application {
    private static MyApplication xxx;

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

更多信息。请点击此LINK

答案 3 :(得分:25)

另一方面,我无法想象一个真正的场景,其中扩展应用程序要么优于另一种方法,要么是完成某些任务所必需的。如果您有一个昂贵的,经常使用的对象,则可以在检测到该对象当前不存在时在IntentService中初始化它。应用程序本身在UI线程上运行,而IntentService在自己的线程上运行。

我更喜欢使用显式Intent将数据从Activity传递到Activity,或者使用SharedPreferences。还有一些方法可以使用接口将数据从Fragment传递到其父Activity。

答案 4 :(得分:8)

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

你也有一点生命周期。

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

答案 5 :(得分:7)

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

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);
    }

答案 6 :(得分:4)

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

例如,您通常通过启动器启动活动,然后“最小化”它。然后启动另一个应用程序(即Tasker),启动另一个活动实例,例如为了创建快捷方式,因为您的应用程序支持android.intent.action.CREATE_SHORTCUT。如果随后创建了快捷方式,并且此活动的快捷方式创建调用将数据修改为应用程序对象,则后台运行的活动将在返回到前台后开始使用此已修改的应用程序对象。

答案 7 :(得分:3)

我看到这个问题没有答案。我延长Application因为我使用Bill Pugh Singleton实现(see reference)而我的一些单身人士需要上下文。 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单例模板可以节省大量时间。

答案 8 :(得分:3)

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

  

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

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

您永远不应该在Application对象中存储可变实例数据,因为如果您认为您的数据将保留在那里,那么您的应用程序将在某些时候因NullPointerException而不可避免地崩溃。应用程序对象不能保证永远留在内存中,它会被杀死。与流行的看法相反,该应用程序将不会从头开始重新启动。 Android将创建一个新的Application对象并启动用户之前的活动,以便首先假定该应用程序从未被杀死。

答案 9 :(得分:1)

使用扩展应用程序只会使您的应用程序确保您在整个应用程序运行期间所需的任何操作。现在它可能是任何类型的变量,并且如果你想从服务器获取一些数据,那么你可以将你的asynctask放在应用程序中,这样它每次都会连续获取,这样你就可以自动获得更新的数据..使用此链接了解更多......

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

答案 10 :(得分:0)

如果通过Application扩展对象,则可以在不创建对象的情况下访问任何类的变量。它们可以被全局调用,并且它们的状态保持不变直到应用程序没有被杀死。

答案 11 :(得分:0)

我认为您可以将Application类用于许多事情,但它们都与您在启动任何活动或服务之前执行某些操作的需求有关。 例如,在我的应用程序中,我使用自定义字体。而不是打电话

Typeface.createFromAsset()

从每个Activity获取来自Assets文件夹的我的字体的引用(这很糟糕,因为它会导致内存泄漏,因为每次调用该方法时都会保留对资产的引用),我是从{{{我的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;
}

Application类的另一个用途是检查设备是否连接到Internet BEFORE需要连接的活动和服务实际启动并采取必要的操作。

答案 12 :(得分:0)

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

您可能会发现有用的其他事情是,按照操作顺序,应用程序先于任何活动启动。在此时间范围内,您可以根据需要准备在第一次活动之前进行的必要的客房整理。

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