Android:从堆栈中删除所有以前的活动

时间:2014-04-30 12:07:01

标签: android

这个问题在很多时候都得到了回答,但没有一个答案可以解决我的问题,所以我想我会问一个新问题。

我的方案如下: 我在我的应用程序中添加了一个导航抽屉,其中包含应用程序每个部分的列表项。点击其中一个启动该应用部分的相应活动。

我想要这样做的方法是让一个主要的活动有抽屉布局,然后其他一切都是碎片,但是应用程序已经有很多活动而且客户不愿意为此付费将这些转换为片段并使其全部工作所需的额外时间。因此,我保持原样,并在每个活动上都有导航抽屉。

当用户点击导航栏中的项目时,将启动该部分的活动。如果用户在抽屉带来的任何活动上按下后退按钮,我希望应用关闭(并返回到Android应用菜单或主屏幕或其他任何内容)。

我的问题是,按下后面只会弹出用户点击抽屉中的项目时之前所处的活动。例如:

  1. 用户在活动A中。
  2. 用户打开抽屉并单击列表项。
  3. 活动B已打开。
  4. 用户按下后退按钮。
  5. 显示活动A.
  6. 我正在寻找一种从堆栈中删除所有先前活动的方法,以便在单击导航项时,已删除堆栈中的所有内容,以便按下新活动将结束应用程序,因为没有任何其他东西可以表现出来。

    我最接近的是使用 FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TASK 标记对导航列表项目点击启动的意图。

    sectionIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    parentActivity.startActivity(sectionIntent);
    

    (其中sectionIntent是新活动的Intent,parentActivity是托管抽屉的活动)。

    这实际上有效,但在旧活动结束和显示新活动之间显示空(黑色)屏幕半秒左右。

    我还考虑过使用LocalBroadcastManager告诉所有活动在"顶级" (因此)活动已经退出,但说实话,这种做法对我来说似乎完全矫枉过正,当然必须有一个更简单的选择?!

    有没有人知道如何防止这种延迟(比如先前的活动在新的活动出现之后被删除)或另一种方法来删除堆栈中的活动?

    先谢谢,各位开发人员:)

    - 解决方案 -

    感谢@Zielony的一个建议,我设法让这个工作。

    我做了一个基本顶级活动并让它发送本地广播以退出应用程序。

    public class AppSectionHomeActivity extends BaseActivity {
    @Override
    public void onBackPressed() {
        sendFinishActivityBroadcast();
        super.onBackPressed();
    }
    
    @Override
    public void finish() {
        sendFinishActivityBroadcast();
        super.finish();
    }
    
    private void sendFinishActivityBroadcast() {
        // Send a local broadcast to all other activities to tell them to close.
        Log.d("AppSectionHomeActivity.sendFinishActivityBroadcast", "Sending broadcast");
        Intent intent = new Intent();
        intent.setAction(Constants.EXIT_APP);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
    

    }

    然后我为所有其他活动(那些不是顶级活动)做了一个基础活动,所以让他们听广播然后如果他们收到它就自己调用finish()。

    public class BaseActivity extends Activity {
    // A broadcast receiver so that we can listen out for feed updated events.
    private BroadcastReceiver exitAppReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            unregisterReceiver();
            // When the activity receives the broadcast to finish up, then do so.
            finish();
        }
    };
    
    @Override
    protected void onResume() {
        super.onResume();
        LocalBroadcastManager.getInstance(this).registerReceiver(exitAppReceiver, new IntentFilter(Constants.EXIT_APP));
    }
    
    @Override
    protected void onDestroy() {
        unregisterReceiver();
        super.onDestroy();
    }
    
    private void unregisterReceiver() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(exitAppReceiver);
    }
    

    }

    这似乎有效!

4 个答案:

答案 0 :(得分:0)

您是否考虑过使用片段代替活动?当事物显示/隐藏/可用等时,这可以提供更大的灵活性。

您是否为每项活动使用新的导航抽屉?

答案 1 :(得分:0)

您有多种选择:

  • 使用Broadcast告诉堆栈关闭自己,然后添加新的Activity。这是一个非常好的解决方案,但似乎你尝试了类似的东西。此外,这表明您不应该尝试关闭多个活动。我不知道背后的思考过程。

  • 使用Process.kill()在退出最近的顶级活动时终止您的应用程序。它看起来像没有堆栈的其余部分退出应用程序。它也不是那么糟糕 - Android无论如何都会关闭未使用的活动,所以它不是那种资源需求。

  • 使用Fragment堆栈。我知道你的客户希望你快速而廉价地做到这一点,但片段堆栈对此非常有用。

  • 使用“任务”将活动和关闭组分组。好像它不适合你,我不知道为什么。这是针对您案例的预片段解决方案。

答案 2 :(得分:0)

你可以这样试试。比如

sectionIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
parentActivity.startActivity(sectionIntent);

祝你好运!

答案 3 :(得分:0)

在清单文件中,您不想在堆栈中进行任何活动,在该活动中进行此更改

 android:noHistory="true"

我希望这对你有用