如何始终从Android上的启动活动开始?

时间:2012-05-04 14:51:22

标签: android

有三种不同的情况:

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

2)用户启动应用,在其中导航,按回家,选择最近并点击应用再次启动我们的应用。

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

我知道旗帜" clearTaskOnLaunch"旗帜,它解决了案例#1。

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

案例#3怎么样?我现在有一个解决方法。但是,我必须把它放在所有可以导致另一个应用程序的活动上。我想知道,是否有更好的方法来解决它(没有在所有这些活动中处理它)。

9 个答案:

答案 0 :(得分:5)

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

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

public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)

您可以使用它,在应用程序级别知道哪些活动被销毁,暂停,恢复等等。每当活动暂停,没有创建/恢复新活动时,您应该清除活动堆叠,然后重新启动startActivity

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

答案 1 :(得分:4)

似乎已经提出了类似的问题。听起来OP提出了一个有效的解决方案。 How do I collapse "child activities"?

编辑: 您可以使用布尔值来判断是否需要折叠回主活动,而不是使用按钮。让您的根活动从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()。就个人而言,我认为这会增加你的意图。希望它有所帮助!

答案 2 :(得分:4)

1)在Class中定义public static normalPause = true变量。

2)在所有活动的onPause方法中设置 false (我很担心。我们可能没有正常停顿)

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

3)在所有活动的onResume中:

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

享受!

答案 3 :(得分: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
}

答案 4 :(得分:1)

也许,android:noHistory正是您所寻找的。如果您使用此属性声明除StartupActivity之外的所有活动,则会在用户离开它们时完成这些活动,并且只会显示StartupActivity

答案 5 :(得分:1)

您可以尝试以下步骤:

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

    if(isFinish)
    {
       finish();
    }
    
  4. 当您打开电子邮件,浏览器等任何原生应用时,
  5. isFinish 值设置为 true

  6. 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,US浏览器等。

    在清单中添加以下权限:

    <uses-permission 
            android:name="android.permission.GET_TASKS" />
    

答案 6 :(得分:0)

您可以在this.finish()的{​​{1}}上致电onPause(),这样就可以在三种情况下关闭活动。

答案 7 :(得分:0)

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

检查这个答案:

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

在应用程序的每个活动中使用Broadcast和BroadcastReceivers,您可以在应用程序进入后台时终止所有活动。

<强>更新

要检测您的应用程序何时可以使用onStop,请检查以了解理论:Activity side-by-side lifecycle

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

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

答案 8 :(得分:0)

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

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

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

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

您可以选择根据需要保存来自呼叫方程序的活动状态。

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

代码段:

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

Bundle bndleData = new Bundle(); 使用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并在后退按钮实现中使用它:

prefix = getPackageName()。toString(); Bundle extras = getIntent()。getBundleExtra(prefix +“bndleData”);

String parentActivity = extras.getString(“ParentActivity”); extras.getString( “PARAMNAME”);

我希望这会对你有所帮助。