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

为什么要扩展Android应用程序类?,android,android-application-class,Android,Android Application Class,扩展的应用程序类可以声明全局变量。还有其他原因吗?应用程序类是具有应用程序整个生命周期的对象。它是应用程序的最高层。可能的用法示例: 当应用程序启动时,可以通过在应用程序类中重写onCreate来添加所需内容 存储从一个活动跳到另一个活动的全局变量。比如异步任务 等 应用程序类是一个单例,您可以从任何活动或具有上下文对象的任何其他位置访问它 您还可以获得一点生命周期 您可以使用应用程序的onCreate方法实例化昂贵但经常使用的对象,如analytics助手。然后,您可以在任何地方访问和使

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

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

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

  • 存储从一个活动跳到另一个活动的全局变量。比如异步任务


应用程序类是一个单例,您可以从任何活动或具有上下文对象的任何其他位置访问它


您还可以获得一点生命周期


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

顺便说一句,我想不出一个真实的场景,在这种场景中,扩展应用程序比其他方法更可取,或者是完成某些事情所必需的。如果您有一个昂贵的、经常使用的对象,当您检测到该对象当前不存在时,可以在IntentService中对其进行初始化。应用程序本身在UI线程上运行,而IntentService在自己的线程上运行


我更喜欢以明确的意图将数据从一个活动传递到另一个活动,或者使用SharedReferences。还有一些方法可以使用接口将数据从片段传递到其父活动。

您可以访问任何类的变量,而无需创建对象(如果其由应用程序扩展)。它们可以被全局调用,并且在应用程序未被终止之前一直保持其状态。

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

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

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

MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();
public static App getAppInstance() {
    return appInstance;
}
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();
    }
}
最后,请记住将应用程序对象用作单例对象:

 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_快捷方式。如果随后创建了快捷方式,并且该快捷方式创建活动调用修改了应用程序对象的数据,则后台运行的活动将开始使用t将其修改后的应用程序对象带回前台。

使用扩展应用程序只需确保应用程序在整个应用程序运行期间能够执行任何类型的操作。现在,它可能是任何类型的变量,假设您要从服务器获取一些数据,则可以将您的异步在应用程序中询问,这样它将每次持续获取数据,这样您将自动获得更新的数据。使用此链接了解更多信息

导言:

  • 如果我们在移动中考虑<代码> APK < /代码>文件,它包括 多个有用的块,例如,
    活动
    s、
    服务
    s和 其他的
  • 这些组件之间不定期通信,并且 别忘了它们有自己的生命周期,这表明 它们可能在某一时刻处于活动状态,而在另一时刻处于非活动状态

  • 要求:
  • 有时,我们可能需要一个场景,其中我们需要访问 变量及其在整个
    应用程序中的状态
    用户正在使用的
    活动
  • 例如,用户可能需要访问保存其 必须通过网络访问的人员信息(如姓名)
    应用程序
  • 我们可以使用SQLite,但要创建一个
    光标
    并再次关闭它 又是表现不好,
  • 我们可以使用
    Intent
    s来传递数据,但它既笨拙又活跃 根据内存可用性的不同,在特定情况下,内存本身可能不存在

  • 应用程序类的用途:
  • 应用程序中访问变量
  • 您可以使用
    应用程序
    启动分析等特定功能 由于应用程序类是在
    活动之前启动的
    s或
    正在运行服务
    s
  • 有一个名为onConfigurationChanged()的重写方法 更改应用程序配置时触发(水平 垂直方向(反之亦然)
  • 还有一个名为onLowMemory()的事件,当 Android设备内存不足

  • 应用程序类的最佳使用。 示例:假设您需要在引导完成后重新启动alarm manager

    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()

    从“资产”文件夹中获取字体引用的每个活动(这很糟糕,因为每次调用该方法时都会保留对资产的引用,这会导致内存泄漏),我是从我的应用程序类中的
    onCreate()
    方法执行此操作的:

    private App appInstance;
    Typeface quickSandRegular;
    ...
    public void onCreate() {
        super.onCreate();
    
        appInstance = this;
        quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
                           "fonts/Quicksand-Regular.otf");
       ...
       }
    
    现在,我也有
    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();
        }
    }
    
    2018-10-19 11:31:55.246 8643-8643/: application created
    2018-10-19 11:31:55.630 8643-8643/: activity created