15

有三种不同的情况:

1)用户启动一个应用程序,在其中导航,按下主页并再次单击应用程序图标以再次启动我们的应用程序。

2)用户启动一个应用程序,在其中导航,按主页,选择最近并单击该应用程序以再次启动我们的应用程序。

3)用户启动一个应用程序,在其中导航,单击应用程序中的某些内容(带有链接的 TextView),这会调用另一个应用程序(例如电子邮件),然后用户单击返回按钮,这会将我们带回到我们的应用程序。

我知道标志“clearTaskOnLaunch”标志,它解决了案例#1。

我知道标志“excludeFromRecents”,它解决了案例#2(可能不是最用户友好的解决方案,但它有效)。

案例#3呢?我现在有一个解决方法。但是,我必须把它放在所有可以引导到另一个应用程序的活动上。我想知道是否有更好的方法来解决它(而不在所有此类活动中处理它)。

4

9 回答 9

6

这应该在应用程序级别处理。

对于 API 级别 14,您可以在 Application 类中注册 ActivityLifeCycleCallback

public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)

您可以使用它来了解在应用程序级别上,哪些活动被销毁、暂停、恢复等。每当一个活动暂停,而没有创建/恢复新活动时,您应该清除活动堆栈,然后重新启动你的开始活动

如果您的目标 SDK 版本 < 14,您应该实现自己的方法,以了解创建/恢复和暂停哪些活动,并且在暂停活动时执行相同操作,而无需创建/恢复新活动

于 2012-05-09T20:27:24.190 回答
4

似乎已经提出了类似的问题。听起来 OP 想出了一个可行的解决方案。如何折叠“子活动”?

编辑:您可以使用布尔值来判断是否需要折叠回主要活动,而不是使用按钮。让您的根活动从 Activity 扩展,而子活动从 CollapsableActivity 扩展。为了让它在所有情况下都能正常工作,我添加了 startOutsideActivity() 和 startOutsideActivityForResult()。

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class CollapsableActivity extends Activity {
    private boolean returnToRoot;
    public static final int COLLAPSE_BACK = -1; // something other than RESULT_CANEL (0)

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        returnToRoot = true;
    }

    @Override
    protected void onStart() {
        super.onStart();
        returnToRoot = true;
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        // start collapsing the stack
        if (returnToRoot) {
            setResult(COLLAPSE_BACK);

            finish();
        }
    }

    @Override
    public void startActivityForResult(Intent intent, int requestCode) {
        super.startActivityForResult(intent, requestCode);
        returnToRoot = false;
    }

    public void startOutsideActivityForResult(Intent intent, int requestCode) {
        super.startActivityForResult(intent, requestCode);
        returnToRoot = true;
    }

    @Override
    public void startActivity(Intent intent) {
        // call startActivityForResult to make sure and catch the collapse condition
        super.startActivityForResult(intent, 0);   
        returnToRoot = false;
    }

    public void startOutsideActivity(Intent intent) {
        super.startActivity(intent);    
        returnToRoot = true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == COLLAPSE_BACK) {
            returnToRoot = true;
        }
   }
}

在您列出的所有情况下,这对我都很有效。唯一的区别是当您离开您的应用程序时,您需要调用 startOutsideActivity() 或 startOutsideActivityForResult()。就个人而言,我认为这可以使您的意图更加清晰。希望能帮助到你!

于 2012-05-06T17:39:48.083 回答
4

1)在一个类中定义一个public static normalPause = true变量。

2)在onPause您所有活动的方法中将其设置为false(我很担心。我们可能不会处于正常暂停状态)

2)在onCreate您所有活动的方法中将其设置为true(别担心。我们处于正常暂停状态)

3) 在onResume您的所有活动中:

if(!Utilities.normalPause)
{
    this.finish()
}

享受!

于 2012-05-08T06:04:38.727 回答
1

我知道您不想在所有活动中管理它,但您可以这样做,并且仍然可以在一个具有超级活动的地方处理代码

public abstract class BlundellActivity extends Activity {
     @Override
     public void onPause(){
         // Whatever strategy you want
     }
}

public class SomeActivity extends BlundellActivity {
     // Do whatever you normally want to do
}

public class SomeActivity extends BlundellActivity {
     // Do whatever you normally want to do here as well
}
于 2012-05-06T18:10:46.663 回答
1

也许,android:noHistory这就是你要找的。如果您声明除此StartupActivity属性之外的所有活动,那么它们将在用户导航离开它们时完成并且只会StartupActivity出现。

于 2012-05-07T07:18:20.053 回答
1

您可以尝试以下步骤:

  1. StartupActivity中使用一个具有默认 false 值的boolean静态标志。isFinish
  2. StartupActivity的onCreate()中将isFinish值设置为false
  3. 在项目中所有活动的onResume()方法中编写以下代码。

    if(isFinish)
    {
       finish();
    }
    
  4. 当您打开任何本机应用程序(如电子邮件、浏览器等)时,将isFinish值设置为true 。

或者

5. 每当您想在后按时关闭应用程序时,在 onBackPress() 方法中将isFinish值设置为true 。

案例 6:如果 Android 浏览器在点击任何链接时打开,则使用下面的代码是 onPause() 方法

if(isBrowserRunning("com.android.browser"))
{
   isFinish = true;
    finish();
}

///////////////

 private boolean isBrowserRunning(String processName)
        {
            ActivityManager manager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
            String packageName = manager.getRunningTasks(1).get(0).topActivity.getPackageName();
            Log.i("LogTest", "Current process package name: " + packageName);

            return processName.equalsIgnoreCase(packageName); 
        }

您可以创建一个示例项目来了解其他浏览器包名称,如opera mini、美国浏览器等。

在清单中添加以下权限:

<uses-permission 
        android:name="android.permission.GET_TASKS" />
于 2012-05-07T09:54:53.600 回答
0

您可以使用一个解决所有问题的解决方案,而不是使用多种解决方案。

检查这个答案:

https://stackoverflow.com/a/8576529/327011

在应用程序的每个活动中使用广播和广播接收器,您可以在应用程序进入后台时终止所有活动。

更新

要检测您的应用程序何时进入后台,您可以使用 onStop,请检查此以了解理论:Activity side-by-side 生命周期

这是实现:https ://stackoverflow.com/a/5862048/327011

我想这就是你所需要的:-)

于 2012-05-09T13:59:56.320 回答
0

您需要使用 bundle 并从调用应用程序传递适当的参数/或参数(即单击应用程序中的某些内容(带有链接的 TextView))。

在被调用的应用程序(电子邮件应用程序)中检索参数。

您可以在参数中发送活动的名称。

现在在电子邮件应用程序(被调用的应用程序)中单击后退按钮导航回您的调用应用程序。

或者,您可以根据需要保存调用程序的活动状态。

您需要使用 Bundle 和 Intent 来实现此逻辑。

代码片段:

在调用程序中,我们需要在被调用程序中存储返回按钮功能所需的参数/数据。

捆绑 bndleData = 新捆绑();使用 Bundle 类的 putString()、putInt() 方法。

    String prefix = getPackageName().toString();
           (this prefix can be stored in application level constants.java file as applicable)

    bndleData.putString("ParentActivity", this.getLocalClassName());

如果需要,还存储其他参数 bndleData.putString("paramName", valueofParamName); bndleData.putInt("IntChannelImage", chImageInt);

    Intent intent = new Intent(v.getContext(), AMRChannelPlayer.class);

    intent.putExtra(prefix + "bndleChnlData", bndleData);

    startActivity(intent);

调用程序:从包中检索数据、活动 nae 并在后退按钮实现中使用它:

前缀 = getPackageName().toString(); Bundle extras = getIntent().getBundleExtra(prefix + "bndleData");

String parentActivity = extras.getString("ParentActivity"); extras.getString("paramName");

我希望这可以帮助你。

于 2012-05-10T15:03:35.850 回答
0

您可以调用您的this.finish(),这样活动将在三种情况下关闭。onPause()Activity

于 2012-05-04T15:39:56.590 回答