【问题标题】:Make app stay in background even if a new activity is launched即使启动了新活动,也使应用程序保持在后台
【发布时间】:2014-02-21 21:09:48
【问题描述】:

我有一个使用启动屏幕和选择屏幕的应用程序,如下面的清单所示:

<application
    android:name="com.example.CoolApp"
    android:label="@string/app_name"
    android:icon="@drawable/app_icon_debug"
    android:theme="@style/Theme.NoBackground">
    <activity
        android:name="com.example.Splash"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:noHistory="true"
        android:launchMode="singleTop">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>

        <intent-filter>
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <data android:scheme="coolappscheme"/>
        </intent-filter>

    </activity>
    <activity
        android:name="com.example.ChoiceActivity"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateHidden"/>
</application>

闪屏显示大约 2 秒,然后通过以下代码导航到 ChoiceActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  ... some stuff for showing the Splash screen ...

  Thread mythread = new Thread() {
    @Override
    public void run() {
      try {
        .. animation stuff for fading in ...

        while (splashActive && ms < splashTime) {
          if(!paused)
            ms=ms+100;
          sleep(100);
        }
      } catch(Exception e) {
      } finally {
        Intent intent = new Intent(Splash.this, ChoiceActivity.class);
        startActivity(intent);
      }
    }
  };

现在,很明显这段代码有很多问题(首先是为什么作者决定使用单独的Thread 而不是AsyncTask。但是,暂时先把这些东西放在一边,如果用户执行以下操作:

  1. 启动应用程序并查看启动画面。
  2. 强制应用程序进入后台(例如,用户接到电话,或者可能只是点击了“主页”按钮)。

然后,当Thread 完成时(即到达finally 块并创建Intent),创建新的ChoiceActivity,但它也将应用程序带到前台。我想禁用此行为。也就是说,我希望加载活动,但应用程序保留在后台。如果这不可能,那么我希望应用程序延迟加载新的Activity(//any// 新的Activity),直到应用程序恢复之后。

我怎样才能做到这一点?

【问题讨论】:

    标签: java android multithreading android-activity background-process


    【解决方案1】:

    Activity 旨在在前台运行。有一个给定的生命周期,它基于用户与应用程序的交互方式。因此,您实际上不应该尝试“在后台启动您的活动”,因为这没有任何意义。您可以做的是以某种方式改变活动对外部事件的反应方式。 例如,您可以在活动中创建一个新的布尔字段,并在每次 onPause() 中将其设置为 false,在 onResume() 中将其设置为 true...

    然后您可以在启动新活动时检查它,实际上只有在为真时才启动它。否则,只需将该字段设置为 true,然后在 onResume() 中启动该字段为 true 的活动。

    您还应该考虑到,后台活动可能随时被系统终止。 Activity 应该释放所有系统资源并在它进入后台时停止它的工作。只有这样你才能确定你的应用程序不会进入不可预测的状态。 对于后台任务,您应该使用服务,这些服务基本上是“没有 UI 的活动”(我不相信我说过)——您的应用程序的一部分在后台运行。

    【讨论】:

    • 嗯,这是一个显而易见的解决方案。我试图确定为什么 Android 文档似乎表明这不应该发生,但它确实发生了。恕我直言,不太可能每个 Android 应用都维护这些内部标志,以确保每个 Activity 在启动新 Activity 之前都不在后台。
    • 为什么应用会在后台启动活动?这没有意义..没有其他应用程序真的不需要这样做..如果您启动一个活动,您可能想向用户展示它..这只是活动的目的
    • 好吧,例如,如果应用程序在加载活动时被中断(例如,用户接听电话或决定应用程序不是他们想要启动的应用程序)。
    • 我可能从我们的代码库中给出了错误的示例。在某些情况下,我们使用AsyncTask 进行一些处理,AsyncTask 在完成后启动一个 Activity。但是,由于我在上面的评论中提到的原因,用户可能希望在处理过程中暂停应用程序。
    • 您应该阅读有关活动生命周期的信息..developer.android.com/training/basics/activity-lifecycle/… 当您的应用程序暂停时,即当它进入后台时,您实际上应该停止它正在做的事情..因为系统可以在任何时候在后台.. Activity 不打算在后台做任何事情..这就是服务的目的。
    猜你喜欢
    • 1970-01-01
    • 2023-01-28
    • 1970-01-01
    • 2021-01-09
    • 2016-06-21
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 2014-05-13
    相关资源
    最近更新 更多