【问题标题】:Resume the Top Activity instead of starting the Launcher Activity恢复 Top Activity 而不是启动 Launcher Activity
【发布时间】:2012-07-28 03:04:25
【问题描述】:

我的应用程序中有两个活动,一个是启动器,另一个是作为第一个的显式调用启动的。

我的问题是,当我从第二个活动按主页键返回主屏幕并启动应用程序时,即使第二个活动已经在后台,第一个活动也会再次启动。

编写第一个 Activity 是为了下载应用程序运行所需的资产,一旦下载了资产,它就会触发第二个 Activity 并为 self 调用完成。

下面是我的应用清单。

<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="14" />

<application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">

    <! Download the Required Assets if not found on SD Card -->
    <activity android:name=".ContentDownload"
        android:screenOrientation="landscape"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|locale" 
        android:launchMode="singleTask"
        android:alwaysRetainTaskState="true">

        <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.SEARCH" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

    </activity>

    <activity android:name=".ActualAppActivity" 
        android:screenOrientation="landscape" 
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|locale" 
        android:launchMode="singleTask"
        android:alwaysRetainTaskState="true"
        />

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>  

<supports-screens android:smallScreens="false" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/>

如果调用启动器并且它在后台,有人可以指导我如何使第二个活动直接获得控制权而不是再次通过第一个活动。

下面是我的 onResult 回调方法。

public void onResult(String assetPath, int result)
{
    if(result == RESULT_OK)
    {
        startActivity(new Intent(this, ActualAppActivity.class));
        activity.destroyDownloadActvity();
        finish();
    }
    else
    {
        finish();
        java.lang.System.exit(0);
    }
    activity.destroyDownloadActvity();
    activity = null;
}

【问题讨论】:

    标签: android android-intent android-manifest android-activity


    【解决方案1】:

    我在我的应用程序的LAUNCHER 活动中使用以下代码来防止应用程序在后台仍然存在并且点击图标时再次启动

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        if (!isTaskRoot()) {
            finish();
            return;
        }
    
        // Rest of your onCreate stuff goes here
    }
    

    这只是完成LAUNCHER Activity 并恢复上次使用的。

    【讨论】:

      【解决方案2】:

      尝试在 Manifest 中指定为 Launcher Activity 的活动的 onCreate 方法中使用以下代码,即问题中发布的原始代码中的 ContentDownload 活动:

      if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
        finish();
        return;
      }
      

      这将通过检测到已经有一个任务正在运行,从而在您的 Launcher Activity 显示之前完成它,并且您的应用应该恢复到最后一个可见的 Activity。

      请参阅 Android 文档中有关 Android 清单启动模式的此页面:http://developer.android.com/reference/android/R.styleable.html#AndroidManifestActivity_launchMode

      【讨论】:

      • 嗨 Jadent,感谢您的回答,尽管这个问题很久以前就发布了,我才意识到我没有选择任何答案。从链接中,我假设您的解决方案应该可以工作并选择此作为答案,但我不再有权访问该项目来验证此行为。
      • 问题是,您应该将代码段复制到每个活动中。
      • 你能提供更多关于标志的信息吗?
      • 在某些设备上不适合我(我的启动画面需要销毁,所以问题几乎相同)。 isTaskRoot() 工作正常(来自我的测试)
      【解决方案3】:

      您的两个活动都使用launchMode="singleTask" 定义。这是你问题的根源。删除它。

      【讨论】:

      • 你想让我在这两个地方完全删除它们还是必须用其他东西替换它们?
      • 两个地方都完全删除。
      • 如果我没有 singleTask,那么我的应用程序中可能有多个相同活动的实例(我之前遇到过,所以放置它解决了我的其他问题),例如当活动在后台启动它时从搜索栏中将启动一个新活动,而不是恢复现有活动。
      • 不,这是解决该问题的错误方法,这就是为什么您首先陷入困境的原因。如果您的应用程序在后台并且您再次启动根活动,通常 Android 只会将现有任务带到前台。它不会创建 Activity 的新实例。
      • 好的,我明白了。如果您从搜索栏中启动应用程序,则活动可能会在另一个任务中结束。在这种情况下,您可以在不同的任务中拥有不同的实例。如果这不是您想要的,那么您可以指定launchMode="singleTask",但用于根活动 (ContentDownload),而不是其他活动。
      【解决方案4】:

      不要调用finish()。您需要将标志 FLAG_ACTIVITY_CLEAR_TASK 和 FLAG_ACTIVITY_NEW_TASK 传递给 Intent。

      Intent intent = new Intent(this, ActualAppActivity.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK| Intent.FLAG_ACTIVITY_NEW_TASK);
      startActivity(intent);
      

      【讨论】:

      • 我会尝试的,但是当它根本不使用时将活动保留在后台是否不必要,而且当我从第二个退出时我不应该返回下载器活动一,我假设如果我不调用它,启动器活动将恢复。
      • 清除任务不起作用,而是再次开始第二个活动,但正在恢复之前被中断的第二个活动...... :(
      • 我认为清除任务或顶部没有任何作用,因为第二个活动没有任何意图过滤器,因此操作系统别无选择,只能调用第一个活动...
      • 如果你不知道之前运行的是什么活动,我有一个奇怪的情况,在某些设备上,即使正在运行的活动被解除(主页按钮),主活动也会被调用press) 不是主要活动。我必须检查堆栈?是吗?
      【解决方案5】:

      没有看到你的代码,我想你想要这样的答案:

      Android finish Activity and start another one

      您需要设置intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);,还需要设置finish() 您的启动器活动。

      【讨论】:

      • 但是你没有打电话给intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 作为我链接的答案也建议。试试看它是否有效。
      • 我刚刚尝试使用 CLEAR TOP 仍然在点击图标时调用已启动但第二个活动从暂停的位置恢复(之前发生的情况相同)...
      • 我认为清除任务或顶部没有任何作用,因为第二个活动没有任何意图过滤器,因此操作系统别无选择,只能调用第一个活动...
      【解决方案6】:

      您可以做的是在持久存储中存储一个字符串,该字符串确定之前是否已加载资产。

      然后,在主活动中,您可以检查资产是否已加载,然后启动所需的活动。

      if(assets_already_downloaded)
        second_activity();
      else
        download_asset_activity();
      

      【讨论】:

      • 下载器活动采用库的形式,因此我无法绕过或更改它的反应方式,必须启动库活动以确定是否下载了资产......跨度>
      • 我在我的问题中更新了 onResult 代码,似乎已经有类似的实现......
      猜你喜欢
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 2018-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-24
      • 2013-02-27
      相关资源
      最近更新 更多