【问题标题】:How to know if Application class was called before Activity launch?如何知道在 Activity 启动之前是否调用了 Application 类?
【发布时间】:2017-09-14 06:43:46
【问题描述】:

我们有Splash extends Activity,这是我们应用程序的起始活动。我们还有CustomApplication extends Application 类,它在调用应用程序进程时被调用。

现在我们有以下要求。 每当应用/进程启动时,调用Utils.doSomeDBWork()函数。

为此,我们将此函数调用放在SplashCustomApplication 类的onCreate() 中。我们将这个调用放在CustomApplication 中的原因是我们的应用程序可以通过deeplinks/notifications 启动,其中Splash 不会被调用。 但问题是,如果应用程序被杀死并通过Splash 启动,那么相同的函数将被调用两次。一个来自CustomApplication,另一个来自Splash

所以基本上我的问题是,如果该函数已经从CustomApplication 调用,那么不要从Splash 调用该函数。我可以考虑通过使用一些静态变量或共享首选项来做到这一点。但不要认为这是一种干净的方式。有没有其他方法可以实现这一点,比如通过Intents 等传递一些信息?

【问题讨论】:

  • 您可以为此使用事件总线。
  • 为什么要从 Activity 中调用函数?仅从您的 Application 类中调用它还不够吗?

标签: android android-activity android-lifecycle


【解决方案1】:

如何知道Application 类在Activity 启动之前被调用?

简而言之,每当Android“收到请求”以启动您的任何应用组件(ActivityServiceBroadcastReceiver)并且您的应用程序还没有运行,它派生了app_process(又名zygote),将其名称更改为在AndroidManifest.xml中定义的your.package.name,初始化Application 实例,调用其onCreate() 方法,然后实例化请求的组件并调用其生命周期方法(ActivityonCreate()ServiceonCreate()BroadcastReceiveronReceive())。

为此,我们将此函数调用放在了splash 和CustomApplication 类的onCreate() 中。

这是多余的。仅从 ApplicationonCreate() 调用它就足够了,这是保证在任何其他组件的生命周期方法之前被调用的应用程序的最早“入口点”。只能有一个 Application 类实例,直到应用进程终止。

您可以通过记录每个生命周期方法来轻松测试它。之后你就没有任何疑问了。

编辑 w.r.t OP 的评论:

如果应用进程正在运行并且用户按下并退出,然后再次启动应用,则不会调用 CustomApplication 类。

这只是部分正确。 CustomApplicationonCreate() 不会被调用,除非系统在后台终止应用程序进程(simulate 就是这种情况,例如,从“最近”中滑动您的应用程序)。

但我们的要求是在这种情况下应该调用CustomApplication 类。

它超出了开发者的范围。只有系统控制

话虽如此,如果 Android 在后台杀死应用程序,CustomApplicationonCreate() 将被调用。如果没有,实现该要求的一种简单方法是在 CustomApplication 中有一个 boolean 标志,这将指示是否调用了 Utils.doSomeDBWork()

【讨论】:

  • 如果应用程序进程正在运行并且用户返回按下并退出,然后再次启动应用程序,则不会调用 CustomApplication 类。但是我们的要求是在这种情况下应该调用 CustomApplication 类。这就是为什么我们把它放在 Splash 类的 onCreate() 方法中。
【解决方案2】:

为什么不只从应用程序的 onCreate 类调用? 当应用程序从深度链接/通知或 Splash 启动时,将始终首先创建应用程序。

您也可以从静态变量中检查。 如下所示。

class Utils{
    public static boolean doneWork = false; // this static variable will be false when app process is killed.

    public doSomeDBWork(){
          if(!doneWork){
              //alreay done..
              return;
          }
          :
          :
          doneWork = true; 
    }

}

【讨论】:

    【解决方案3】:

    您可以在应用层使用ActivityLifeCycleCallbacks 进行一些控制。如果在 splashActivity 中使用它是您的解决方案,请跟踪您的活动并在您的回调中进行调用。我希望它提供一个想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-20
      • 1970-01-01
      • 1970-01-01
      • 2012-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多