从另一个活动中完成一个活动


100

我想从另一个活动中完成一个活动,例如:

在活动[A]中,单击按钮时,我在不完成活动[A]的情况下调用活动[B]。

现在在活动[B]中,有两个按钮,“ 新建”和“ 修改”。当用户单击“修改”时,从堆栈中弹出活动[A],并勾选所有选项。

但是当用户单击“ 新建”时活动[B]中的“按钮时,我将不得不从堆栈中完成活动[A],然后再次将该活动[A]重新加载到堆栈中。

我正在尝试,但是无法完成堆栈中的活动[A] ...我该怎么做?

我将代码用作:

从活动[A]:

Intent GotoB = new Intent(A.this,B.class);
startActivityForResult(GotoB,1);

同一活动中的另一种方法

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

    if (requestCode == 1)
    {
        if (resultCode == 1) {
            Intent i = getIntent();
            overridePendingTransition(0, 0);
            i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            finish();

            overridePendingTransition(0, 0);
            startActivity(i);
        }
    }
}

在活动[B]中,单击按钮:

setResult(1);
finish();

嘿,您想从另一项权利中完成一项活动...然后我发布了正确的答案。但是,您为什么反对呢?
Manjunath 2012年

有一个带几个漂亮的一个线程答案在这里: stackoverflow.com/questions/14355731/...
AB

Answers:


188
  1. 在清单文件中将您的活动设为A: launchMode = "singleInstance"

  2. 当用户单击新建时,请执行FirstActivity.fa.finish();并调用新的Intent。

  3. 当用户单击“修改”时,调用新的Intent或仅完成活动B。

第一路

在您的第一个活动中,这样声明一个Activity object

public static Activity fa;
onCreate()
{
    fa = this;
}

现在在另一个对象中使用该对象Activity来完成首次操作,

onCreate()
{
    FirstActivity.fa.finish();
}

第二种方式

FirstActivity继续前进时,您要拨打要完成的活动时,可以在通话时添加标志FirstActivity

intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

但是,即使您不希望使用该标志,该活动也会完成。有时onBack如果您想显示,FirstActivity则必须使用Intent进行调用。


6
好答案..!
Vaibhav Vajani 2012年

93
您持有对活动的静态引用。除非您从某个地方手动清除它,否则这将永远不会消失->您正在制造内存泄漏!
DArkO 2012年

5
好吧,您可以开箱即用的思维给我+1:D,我只想改成singleTop。但是在执行类似操作时,它仍然不是我的首选。通过清理代码,我的意思是一种摆脱静态引用的方式,因此不会发生内存泄漏,但这取决于应用程序的结构。
DArkO'4

6
请没有人使用第一种解决方案,这是完全错误的。您在创建僵尸对象的同时,以一种真正的技巧绕过了Android框架。使用广播接收器。
S-K”

1
很棒的解决方案。对于我要从活动A-> B-> C转到C的onBackPressed的问题,我运行得很好,但是我正在启动B的新实例。但是如果我对B的该新实例执行onBackPressed,它就可以转到B的旧实例,而不是A的旧实例(我想要的)。因此,我在C的onBackPressed中遵循了您的第一个方法,它给了我我想要的行为:)非常感谢:)
SoulRayder 2014年

87

您可以做到,但是我认为您不应该中断正常的活动流程。如果您想结束活动,则只需从活动B向活动A发送广播。

在开始活动B之前,创建一个广播接收器:

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context arg0, Intent intent) {
        String action = intent.getAction();
        if (action.equals("finish_activity")) {
            finish();
            // DO WHATEVER YOU WANT.
        }
    }
};
registerReceiver(broadcastReceiver, new IntentFilter("finish_activity"));

要从B完成活动A时,将广播从活动B发送到活动A

Intent intent = new Intent("finish_activity");
sendBroadcast(intent);

我希望它对您有用...


它在“ registerReceiver(broadcast_reciever,新的IntentFilter(“ finish_activity”));“上显示此错误“令牌上的语法错误,应改为AnnotationName”。怎么了?
Behzad 2012年

2
“您不应该破坏正常的活动流程” +1
S-

11
不要忘记注销broadcast_receiverunregisterReceiver()
JAEC


这是解决方案。好人
Parinda Rajapaksha

17

这是一个相当标准的沟通问题。一种方法是在活动A中使用ResultReceiver:

Intent GotoB=new Intent(A.this,B.class);
GotoB.putExtra("finisher", new ResultReceiver(null) {
    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        A.this.finish();
    }
});
startActivityForResult(GotoB,1);

然后在活动B中,您可以按需完成它,如下所示:

((ResultReceiver)getIntent().getExtra("finisher")).send(1, new Bundle());

尝试类似的事情。


6
+1,(((ResultReceiver)getIntent()。getParcelableExtra(“ finisher”))。send(1,new Bundle());
Hamidreza Sadegh 2014年

12

在您的情况下,可以使用一种方法。

步骤1:从活动A启动活动B

startActivity(new Intent(A.this, B.class));

第2步:如果用户使用FLAG_ACTIVITY_CLEAR_TOP。单击修改按钮启动活动A ,也请额外传递该标志。

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "modify");
startActivity(i);
finish();

第3步:如果用户使用FLAG_ACTIVITY_CLEAR_TOP。单击添加按钮启动Activity A,则另外传递该标志。FLAG_ACTIVITY_CLEAR_TOP将清除所有打开的活动直至目标,如果目标活动中未定义启动模式,则重新启动

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "add");
startActivity(i);
finish();

步骤4:现在onCreate(),活动A的方法需要检索该标志。

String flag = getIntent().getStringExtra("flag");
if(flag.equals("add")) {
    //Write a code for add
}else {
    //Write a code for modifying
}

6

从请求代码开始您的活动:

StartActivityForResult(intent,1234);

您可以从任何其他活动中将其关闭,例如:

finishActivity(1234);

用什么语言?
Morten Holmgaard

5

请参阅我对“堆栈溢出”问题的回答。完成所有先前的活动

您需要添加Intent.FLAG_CLEAR_TOP。该标志确保堆栈中目标活动之上的所有活动均已完成,并且已显示该活动。

您需要的另一件事是 SINGLE_TOP标志。如果堆栈中已经创建了一个新活动,则通过此活动您可以防止Android创建新活动。

请注意,如果已经创建了活动,则带有这些标志的意图将onNewIntent(intent)在目标活动中称为(您需要重载它以进行处理)的方法中传递。

然后,onNewIntent您将拥有一个称为restart的方法,或者将调用它finish()并对其自身启动新意图的repopulate()方法,或者具有一个将设置新数据的方法。我更喜欢第二种方法,因为它比较便宜,而且您始终可以将onCreate逻辑提取 到一个单独的方法中,以进行填充。


4

我刚刚应用了Nepster的解决方案,并且像一个护身符一样工作。有一个小的修改可以从Fragment运行它。

到你的片段

// sending intent to onNewIntent() of MainActivity
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.putExtra("transparent_nav_changed", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

并要重新启动Activity的OnNewIntent()。

// recreate activity when transparent_nav was just changed
if (getIntent().getBooleanExtra("transparent_nav_changed", false)) {
    finish(); // finish and create a new Instance
    Intent restarter = new Intent(MainActivity.this, MainActivity.class);
    startActivity(restarter);
}

2

我认为我有最简单的方法...按下B中的new。

Intent intent = new Intent(B.this, A.class);
intent.putExtra("NewClicked", true);
 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

并在A中得到它

  if (getIntent().getBooleanExtra("NewClicked", false)) {
        finish();// finish yourself and make a create a new Instance of yours.
      Intent intent = new Intent(A.this,A.class);
      startActivity(intent);
    }

1

我知道这是一个老问题,其中一些方法对我不起作用,所以对于任何希望将来或遇到麻烦的人

我覆盖onPausefinish()在该方法内调用。


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.