在启动器中通过按图标启动时,应用程序完全重新启动


79

我正在尝试发布第一个Android应用的发布版本,以发送给一些测试人员。但是,我遇到了一个问题。当您退出该应用程序,然后通过其图标启动它以重新输入它时,它将重新启动整个应用程序,而不是返回到其先前的位置。即使退出后立即重新进入,也会发生这种情况。但是,如果我按住“主页”按钮并通过最近的应用程序列表启动它,则不会发生。

我在网上搜索了其他有此问题的人,但有几个人,但没人能确切地知道为什么会发生这种问题。有人建议在旧问题中将清单文件中的启动模式设置为singletask或singleinstance,但这并没有帮助我,而且-从我的理解来看,android的默认行为是返回到任务的先前状态在这种情况下,所以我不知道为什么我需要特殊的清单选项才能做到这一点。

关于此问题的最奇怪的事情是,如果我使用eclipse和调试器将应用程序放在手机上,则不会发生此问题。我什至不需要连接到调试器,似乎只要我有该应用程序的调试版本,就不会发生此问题。但是,如果我使用发行版(我使用Eclipse中的“ Android工具-导出签名的应用程序包”菜单选项创建它),则会出现问题。如果有人对导致这种情况的原因有任何见解,我很想听听您的想法。


2
因此,显然,如果我重新启动安装该应用程序的设备,则此问题将不复存在。现在,一切都很酷,但是对于我的应用程序而言,如果用户在下载手机重新启动手机之前以这种方式运行,对于用户来说仍然会非常烦人。
LayfieldK

您可以提供一个堆栈跟踪或日志吗?
TryTryAgain

2
不,仅当我使用应用程序的发行版时才会发生,因此我没有堆栈跟踪或日志。
LayfieldK

3
我遇到了同样的问题,您是否找到解决办法?还是原因?甚至在重新启动设备后能够重新创建行为?-顺便说一句,我还发现强制停止应用程序可以清除行为
kassim

2
此问题的有效答案可以在这里找到:stackoverflow.com/questions/19545889/...
Mythul

Answers:


58

我在应用程序中遇到了同样的问题,我解决了添加标志"android:launchMode="singleTop""而不是"android:launchMode="singleTask""<activity>AndroidManifest.xml文件的声明中添加标志的问题。希望这会帮助到别人。


3
如果我们要使用不同的数据打开同一活动两次,则此方法很危险。
hkaraoglu's

6
如果要使用不同的数据打开同一活动,则可以在onNewIntent()中进行处理。
塔斯

我还发现是否只是android:launchMode完全删除了起作用的属性。不知道它是否默认为“标准”,但是任何想法都会有所帮助。我发现这个伟大的解释,但它的晚,所以它看起来像外语我现在:inthecheesefactory.com/blog/...
约书亚品特

嗨,我应该在所有活动中添加android:launchMode =“ singleTop”吗?
jmarkstar

就我而言,这不起作用。在我的应用程序中,我具有创建和共享内容链接的功能。如果应用程序在后台,并且用户单击共享链接,则在我的launchMode设置为“ singleTop”或“ singleInstance”的情况下,它会打开该应用程序的全新实例。
tech_human19年

33

到目前为止,我发现这是一个问题,具体取决于您如何在实际设备中安装它:

  1. 如果您只是简单地将APK复制并粘贴到设备的本地存储中,然后再从设备上安装APK,无论它是签名的还是未签名的,还是从bin文件夹中获取的,它都会显示此行为,应用将从菜单图标重新启动。

如果使用以下选项之一安装它,则不会出现此问题:

  1. 使用终端或命令提示符转到sdk / tools /,然后键入

    adb install <FILE PATH OF .APK FILE>
    

    在Linux中,键入:

    ./adb install <FILE PATH OF .APK FILE>
    
  2. 只需从Eclipse运行您的项目。

我很高兴知道是否有可能分发正确的APK以进行Beta测试。我已经尝试导出签名的APK,因为当您复制和粘贴APK并手动安装它时,它会显示恶意行为。

更新:

我找到了解决方案。请遵循以下两个步骤:

  1. 活动标记内的AndroidMainifest.xml中android:launchMode="singleTask" = true为应用程序的所有活动设置。
  2. 将此代码放在启动器活动的中onCreate()

    if (!isTaskRoot())
    {
        final Intent intent = getIntent();
        final String intentAction = intent.getAction(); 
        if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
            finish();
            return;       
        }
    }
    

此行为是Android中的错误。不是特例。


2
我不会推荐这个。launchMode不应仅设置。它必须要有一个目的,因为它可能导致奇怪的行为(说出经验;))
Boy

如果您的应用程序支持Pin Lock之类的功能,则在设置android:launchMode =“ singleTask”时应谨慎对待。
Logan Guo

10

另一个奇怪的原因,仅在通过复制到设备并安装后单击“打开”启动应用程序时,重启才会发生。

在OS8.1上测试,没有活动的launchMode。

在此处输入图片说明


有什么解决办法吗?
Abhay Koradiya,

7

您可以将launchMode用作AndroidManifest.xml中启动器活动的singleTop

       <activity
        android:name="<YOUR_ACTIVITY>"
        android:label="@string/app_name"
        android:launchMode="singleTop">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

4
 // To prevent launching another instance of app on clicking app icon 
        if (!isTaskRoot()
                && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
                && getIntent().getAction() != null
                && getIntent().getAction().equals(Intent.ACTION_MAIN)) {

            finish();
            return;
        }

在调用setContentView之前,在启动器活动中编写以上代码。这样可以解决问题


3

这是Android中的默认行为。对于调试版本,由于某些原因,它的工作方式有所不同。可以通过添加android:launchMode="singleInstance"活动来解决该问题,您要在从图标启动后重新启动。


3

将此添加到您的第一个活动:

if (!isTaskRoot()) {
        finish();
        return;
}     
super.onCreate(savedInstanceState);

2
这适用于我的情况,女巫的启动屏幕可以处理应用程序的所有入口点,因此,如果启动屏幕已经完成了它的工作,并且第一次将其重定向到正确的位置,则无需再次进行操作
Ahmed na

2

尝试使用android:alwaysRetainTaskState,如以下示例所示:

<activity
    android:name="com.jsnider.timelineplanner.MainActivity"
    android:alwaysRetainTaskState="true"
    android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

2

对我来说,我发现自己NoHistory = true在活动属性中发布了错误的信息

[Activity(NoHistory = true, ScreenOrientation = ScreenOrientation.Landscape)]

这阻止了该应用恢复到该活动并重新启动


1

您可以尝试android:alwaysRetainTaskState="true"在AndroidManifest.xml中设置启动器活动。

    <activity
        android:name=".YourMainActivity"
        android:alwaysRetainTaskState="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

有关详细信息,请参见https://developer.android.com/guide/topics/manifest/activity-element.html#always


1

我在2019年的Android TV上看到了这个问题。有更好的解决方法吗?以外

if (!isTaskRoot()) {
    finish();
}

它可以工作,但看起来比实际解决方案更像是骇客。


0

上面的所有解决方案在我的所有设备上均无法正常运行。它适用于部分三星,但并非全部。

对我来说,问题的原因是手动安装APK。


0

对我而言,此修复方法是LaunchMode = LaunchMode.SingleTop在“主要活动”上添加到“活动”属性中:

/// <summary>
    /// The main activity of the application.
    /// </summary>
    [Activity(Label = "SilhuettePhone",
        Icon = "@drawable/icon",
        Theme = "@style/MainTheme",
        MainLauncher = true,
        ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
        ScreenOrientation = ScreenOrientation.Portrait,
        LaunchMode = LaunchMode.SingleTop,
        WindowSoftInputMode = SoftInput.AdjustResize)]

-1

当您在Android中按下“后退”按钮时,该onDestroy方法将被调用(与按下“主页”按钮(仅在其中onPause()调用该方法)相反)。

如果需要您的应用程序从上次停止的地方继续,请在您的onDestroy()方法中保存应用程序的状态,然后在方法中加载该状态onCreate()


1
我按下主页按钮退出该应用程序。
LayfieldK
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.