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

Android 从另一个活动中完成一个活动,android,android-intent,android-activity,Android,Android Intent,Android Activity,我想从另一个活动中完成一个活动,如: 在活动[A]中,单击按钮,我正在调用活动[B],而没有完成活动[A] 现在在活动[B]中有两个按钮,新建和修改。当用户单击modify时,然后从堆栈中弹出一个活动[A],并勾选所有选项 但是,当用户单击活动[B]中的新按钮时,我必须从堆栈中完成活动[A],并再次将该活动[A]重新加载到堆栈中 我正在尝试,但无法从堆栈中完成活动[A]。。。我怎么做 我将代码用作: 从活动[A]: Intent GotoB = new Intent(A.this,B.class

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

在活动[A]中,单击按钮,我正在调用活动[B],而没有完成活动[A]

现在在活动[B]中有两个按钮,新建修改。当用户单击modify时,然后从堆栈中弹出一个活动[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();

您需要的是添加
Intent.FLAG\u CLEAR\u TOP
。此标志确保堆栈中目标活动上方的所有活动都已完成并显示一个

您需要的另一件事是
SINGLE_TOP
标志。如果堆栈中已经创建了一个活动,那么使用这个活动可以阻止Android创建一个新活动

请注意,如果活动已经创建,那么带有这些标志的意图将在目标活动中名为
onNewIntent(intent)
的方法中传递(您需要重载它来处理它)

然后在
onNewIntent
中,您有一个名为restart的方法,或者调用
finish()
并向自身启动新意图的方法,或者有一个将设置新数据的
repopulate()
方法。我更喜欢第二种方法,它比较便宜,而且您可以随时提取
逻辑创建为一个单独的方法,您可以调用该方法进行填充。

您可以这样做,但我认为您不应该破坏正常的活动流程。如果你想完成你的活动,那么你可以简单地从活动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);

我希望它对你有用…

这是一个相当标准的沟通问题。一种方法是在活动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());
试试那样的

  • 将您的活动设置为清单文件:
    launchMode=“singleInstance”

  • 当用户单击new时,执行
    FirstActivity.fa.finish()
    并调用新的Intent

  • 当用户单击“修改”时,调用新的意图或简单地完成活动B

  • 第一条路

    在第一个活动中,像这样声明一个
    活动对象

    public static Activity fa;
    onCreate()
    {
        fa = this;
    }
    
    onCreate()
    {
        FirstActivity.fa.finish();
    }
    
    现在在另一个
    活动中使用该对象来完成第一个这样的活动

    public static Activity fa;
    onCreate()
    {
        fa = this;
    }
    
    onCreate()
    {
        FirstActivity.fa.finish();
    }
    
    第二种方式

    在调用要在继续时立即完成的活动
    FirstActivity
    时, 您可以在调用
    FirstActivity

    intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    

    但使用此标志,即使您不希望活动完成,它也会完成。如果您想显示
    第一个活动
    ,有时必须使用意图调用它。

    在您的案例中可以使用一种方法

    步骤1:从活动A开始活动B

    startActivity(new Intent(A.this, B.class));
    
    步骤2:如果用户单击“修改”按钮,则使用
    标志\u活动\u清除\u顶部启动活动A
    。此外,还应额外传递该标志

    Intent i = new Intent(B.this, A.class);
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.putExtra("flag", "modify");
    startActivity(i);
    finish();
    
    步骤3:如果用户单击添加按钮,则使用
    标志\u活动\u清除\u顶部
    启动活动A。此外,还应额外传递标志<代码>标记\活动\清除\顶部
    将清除目标活动之前所有打开的活动,如果目标活动中未定义启动模式,则重新启动

    Intent i = new Intent(B.this, A.class);
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.putExtra("flag", "add");
    startActivity(i);
    finish();
    
    步骤4:现在活动A的
    onCreate()
    方法需要检索该标志

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

    我想我有最简单的方法。。。在B.中按下新按钮

    Intent intent = new Intent(B.this, A.class);
    intent.putExtra("NewClicked", true);
     intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    
    一下子就明白了

      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);
        }
    

    我刚刚应用了Nepster的解决方案,效果很好。有一个小的修改可以从片段运行它

    你的碎片

    // 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);
    
    以及要重新启动的活动的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);
    }
    

    我知道这是一个老生常谈的问题,这些方法中的一些对我不起作用,所以对于那些展望未来或有我的麻烦的人来说,这对我起作用了


    我覆盖了暂停时的
    onPause
    ,并在该方法中调用了
    finish()

    首先调用
    startactivity()
    ,然后使用
    finish()
    使用请求代码启动活动:

    StartActivityForResult(intent,1234);
    
    您可以通过以下任何其他活动将其关闭:

    finishActivity(1234);
    

    嘿,你想完成另一项活动,对吧。。。然后我发布了正确的答案。但是,你为什么要否决它呢?这里有一条线索,有几个很好的答案:你持有一个对活动的静态引用。除非您从某个地方手动清除->您正在创建内存泄漏,否则这将永远不会消失!好吧,没关系,你有我的+1开箱即用的想法:D,我只需要换成单顶。然而,当我做类似的事情时,它仍然不是我的第一选择。我所说的清理代码是指一种摆脱静态引用的方法,这样就不会有内存泄漏,但这取决于应用程序的结构。请不要使用第一种解决方案,这是完全错误的。在创建僵尸对象时,您正在以一种非常黑客的方式绕过Android框架。使用广播接收器。很棒的解决方案。对于我的问题来说效果很好,我从活动A->B->C开始,在返回C时,我启动了新的B实例。但是如果我返回了新的B实例,它会返回到旧的B实例,而不是旧的A实例(我想要的)。所以我在C的onBackPressed中遵循了你的第一个方法,它给了我想要的行为