【问题标题】:Finish all activities at a time一次完成所有活动
【发布时间】:2012-12-09 17:33:39
【问题描述】:

我有一个包含多个页面的应用程序,即多个活动,其中一些保持打开状态。

有没有办法一次关闭所有活动?

【问题讨论】:

  • 您能否更详细地描述您的应用/场景?通常不需要一次关闭所有活动。

标签: android android-activity activity-finish


【解决方案1】:
@Override
    public void onBackPressed(){
        MaterialAlertDialogBuilder alert = new MaterialAlertDialogBuilder(BorrowForm.this, MyTheme);
        alert.setTitle("Confirmation");
        alert.setCancelable(false);
        alert.setMessage("App will exit. Data will not be saved. Continue?");
        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast toast = Toast.makeText(BorrowForm.this, "App terminated.", Toast.LENGTH_SHORT);
                toast.getView().setBackgroundColor(Color.parseColor("#273036"));
                toast.setGravity(Gravity.CENTER_HORIZONTAL,0,0);
                TextView toastMessage=(TextView) toast.getView().findViewById(android.R.id.message);
                toastMessage.setTextColor(Color.WHITE);
                toast.show();
                finishAffinity();
            }
        });
        alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        alert.setCancelable(false);
        alert.show();
    }

【讨论】:

    【解决方案2】:

    其他答案都不适合我。但我又研究了一些,终于得到了答案。

    您实际上要求根据我的需要关闭应用程序。所以,添加以下代码:

    finishAffinity();

    【讨论】:

    • 这是否完成所有活动...?或者,只有当前活动?
    • 所有活动因应用而运行。
    • 如果我清除所有以前的打开活动并保持当前活动打开怎么办?
    【解决方案3】:

    moveTaskToBack(true);

    //将此添加到点击列表中

    【讨论】:

      【解决方案4】:
      in LoginActivity
      
      @Override
          public void onBackPressed() {
              Intent startMain = new Intent(Intent.ACTION_MAIN);
              startMain.addCategory(Intent.CATEGORY_HOME);
              startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
              startActivity(startMain);
              finish();
              super.onBackPressed();
          }
      

      【讨论】:

        【解决方案5】:

        您可以使用以下代码:

        Intent i = new Intent(OldActivity.this, NewActivity.class);
        
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        
        startActivity(i);
        

        【讨论】:

          【解决方案6】:

          关闭应用

          Intent intent = new Intent(getApplicationContext(), Splash_Screen.class);
                          intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                          intent.putExtra("EXIT", true);
                          startActivity(intent);
          

          把这个放在 oncreate 和 onResume 打开的第一个活动。 前任。正在启动屏幕活动

          if (getIntent().getBooleanExtra("EXIT", false)) {
                      this.finish();
                      System.exit(0);
                  }
          

          【讨论】:

            【解决方案7】:

            您可以使用finishAffinity() 方法来完成当前活动和所有父活动。但它只适用于API 16+

            API 16+ 使用:

            finishAffinity();
            

            API 16 以下使用:

            ActivityCompat.finishAffinity(this); //with v4 support library
            

            退出整个应用:

            finishAffinity(); // Close all activites
            System.exit(0);  // closing files, releasing resources
            

            【讨论】:

            • 请不要对多个问题发布相同的答案。发布一个好的答案,然后投票/标记以关闭其他问题作为重复问题。如果问题不是重复的,调整您对该问题的回答。
            • 谢谢先生帮我解决这个问题。
            【解决方案8】:

            使用

            finishAffinity ();
            

            代替:

            System.exit(); or finish();
            

            它退出完整的应用程序或所有活动。

            【讨论】:

              【解决方案9】:

              finishAffinity() 的问题是只有您当前任务中的活动被关闭,但singleInstancelaunchMode 和其他任务中的活动仍然打开并在finishAffinity() 之后被带到前台。 System.exit(0) 的问题在于,您使用所有后台服务和所有分配的内存完成您的 App 进程,这可能会导致不良副作用(例如不再接收通知)。

              这里还有其他两个解决这两个问题的替代方案

              1. 在您的应用程序类中使用ActivityLifecycleCallbacks 注册创建的活动并在需要时关闭它们:https://gist.github.com/sebaslogen/5006ec133243379d293f9d6221100ddb#file-myandroidapplication-kt-L10
              2. 在测试中你可以使用ActivityLifecycleMonitorRegistry:https://github.com/sebaslogen/CleanGUITestArchitecture/blob/master/app/src/androidTest/java/com/neoranga55/cleanguitestarchitecture/util/ActivityFinisher.java#L15

              【讨论】:

              • 这似乎是最好的答案
              • 现在最好的答案,这要归功于生命周期活动,无需控制它们的状态或意图
              【解决方案10】:

              Activity 中有一个finishAffinity() 方法可以完成当前活动和所有父活动,但它仅适用于 Android 4.1 或更高版本。

              对于 API 16+,使用

              finishAffinity();
              

              对于更低版本(Android 4.1 更低版本),请使用

              ActivityCompat.finishAffinity(YourActivity.this);
              

              【讨论】:

              【解决方案11】:

              我找到的最佳解决方案,与 API 级别 的设备兼容

              Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
              ComponentName cn = intent.getComponent();
              Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
              startActivity(mainIntent);
              

              此解决方案需要 Android 支持库

              【讨论】:

              • 不错,这是最好的
              • 工作很棒......谢谢
              【解决方案12】:

              对于 API 16+,使用

              finishAffinity();
              

              对于较低的,使用

              ActivityCompat.finishAffinity(YourActivity.this)
              

              【讨论】:

              • 能否请您为您的答案添加更多上下文。仅代码的答案很难理解。如果您可以在帖子中添加更多信息,这将对提问者和未来的读者都有帮助。
              【解决方案13】:

              以下两个标志对我有用。他们会清除所有之前的活动并开始新的活动

                Intent intent = new Intent(getApplicationContext(), MyDetails.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
              

              希望这会有所帮助。

              【讨论】:

                【解决方案14】:

                您可以存储一个布尔标志来表示是否所有活动都应该完成(在您的共享偏好中更喜欢)然后每个活动的onStart() 方法应该有类似的内容:

                SharedPreferences pref=PreferenceManager.getDefaultSharedPreferences(this);
                boolean needToDestroyFlag=pref.getBoolean("destroyFlag", false);
                if(needToDestroyFlag)
                {
                    finish();
                }else
                {
                    //...
                }
                

                显然,当您需要完成所有活动(在当前活动中)之后,您可以像下面这样设置此标志,您可以在当前活动上调用 finish() 方法,这将导致终止当前活动并从堆栈中弹出活动一个一个地执行,每一个的 onStart() 方法都会执行并导致它终止:

                SharedPreferences.Editor editor=PreferenceManager.getDefaultSharedPreferences(this).edit();
                editor.putBoolean("destroyFlag", true);
                editor.apply();
                

                如果您使用@letsnurture 建议的方法,您将面临@gumuruh 提出的问题。

                【讨论】:

                • 感谢您的方法,它帮助了我。我使用静态类变量而不是共享首选项做了类似的事情,它在整个应用程序生命周期中都存在。在每个activity的onResume中,调用super.onResume(); if (ExitHelper.isExitFlagRaised) { this.finish(); }。虽然它可能无法完成所有活动,但它确实完成了会自动恢复的活动。
                【解决方案15】:

                如果植根:

                Runtime.getRuntime().exec("su -c service call activity 42 s16 com.example.your_app");
                

                【讨论】:

                  【解决方案16】:

                  你可以试试 finishAffinity() ,它关闭所有当前活动以在 v4.1 以上工作

                  【讨论】:

                    【解决方案17】:

                    如果您正在寻找一种似乎更“按部就班”且在方法上设计(使用广播接收器)的解决方案,您最好查看以下链接:http://www.hrupin.com/2011/10/how-to-finish-all-activities-in-your-android-application-through-simple-call

                    该链接中出现的建议实现需要稍作更改 - 您应该使用 sendStickyBroadcast(Intent) 方法(不要忘记将 BROADCAST_STICKY 权限添加到您的清单)而不是 sendBroadcast(Intent),以便使您暂停的活动能够接收广播并对其进行处理,这意味着您还应该在重新启动应用程序时通过在打开活动的 onCreate() 方法中调用 removeStickyBroadcast(Intent) 方法来删​​除该粘性广播。

                    虽然上面提到的基于 startActivity(...) 的解决方案,乍一看 - 似乎非常好、优雅、简短、快速且易于实现 - 他们觉得有点“错误”(开始一个活动 - 使用所有可能需要和涉及的开销和资源,只是为了杀死它?...)

                    【讨论】:

                      【解决方案18】:

                      我是 java/android 的初学者,也许这个简单的解决方案对你有帮助

                      FIRST,创建静态类

                      public class ActivityManager {
                      
                          static Activity  _step1;
                          static Activity _step2;
                          static Activity _step3;
                      
                          public static void setActivity1(Activity activity)
                          {
                              _step1 = activity;
                          }
                      
                          public static void setActivity2(Activity activity)
                          {
                              _step2 = activity;
                          }
                      
                          public static void setActivity3(Activity activity)
                          {
                              _step3 = activity;
                          }
                      
                          public static void finishAll()
                          {
                              _step1.finish();
                              _step2.finish();
                              _step3.finish();
                          }
                      
                      }
                      

                      那么当您运行新的活动保存链接到您的经理时(在第 1 步中):

                      ActivityManager.setActivity1(this);
                      AddValuesToSharedPreferences();
                      Intent intent = new Intent(Step1.this, Step2.class);
                      startActivity(intent);
                      

                      然后在最后一步完成所有操作:

                       public void OkExit(View v) throws IOException {
                              ActivityManager.finishAll();
                          }
                      

                      【讨论】:

                      • 永远不要持有对活动的静态引用。活动使用相对大量的内存,当活动进入后台时应该释放这些内存。只要进程还活着,静态引用就会被保存,这对于应用程序来说意味着永远。作为开发人员和用户,这对您都不利。
                      • 全局变量是严重的反模式。
                      • 太糟糕了。绝不能保留对活动的全局引用。
                      【解决方案19】:

                      我也在为同样的问题而苦苦挣扎。打开关于页面并从那里调用finish(); 并没有关闭应用程序,而是转到以前的活动,我想从关于页面本身关闭应用程序。

                      这是对我有用的代码:

                      Intent startMain = new Intent(Intent.ACTION_MAIN); 
                      startMain.addCategory(Intent.CATEGORY_HOME); 
                      startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
                      startActivity(startMain); 
                      finish();
                      

                      希望这会有所帮助。

                      【讨论】:

                        【解决方案20】:

                        当您希望退出所有打开的活动时,您应该按下一个按钮,该按钮会加载在您的应用程序启动时运行的第一个活动,然后清除所有其他活动,然后完成最后一个剩余活动。 为此,请在您的项目中应用以下代码

                        Intent intent = new Intent(getApplicationContext(), FirstActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        intent.putExtra("EXIT", true);
                        startActivity(intent);
                        

                        上面的代码完成了除FirstActivity之外的所有活动。 然后我们需要完成FirstActivity的 在Firstactivity的oncreate中输入如下代码

                        if (getIntent().getBooleanExtra("EXIT", false)) {
                            finish();
                        }
                        

                        你已经完成了......

                        【讨论】:

                        • 但是这段代码会让你的“返回”按钮不再像往常一样工作。当您单击“返回”按钮时,它将关闭所有内容。那么如何处理/@letsnurture 呢?
                        • putExtra 是做什么的?
                        • @letsnurture 活动将保留在最近的应用列表中
                        • 启动表单接收器时可以做什么。我尝试了您的建议,但它不起作用...有什么建议吗?
                        • Intent intent = new Intent(getApplicationContext(), LoginActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);开始活动(意图);
                        【解决方案21】:

                        清除活动历史的三种解决方案。

                        1) 你可以通过intent在开始新活动的时候写finish()

                        2) 在 Androidmanifest.xml 文件中的所有<activity> 标签中写入android:noHistory="true",如果您打开新活动并且您当时没有编写finish(),则使用此标记,之前的活动总是完成,在写入您的之后活动看起来像这样。

                        <activity
                            android:name=".Splash_Screen_Activity"
                            android:label="@string/app_name"
                            android:noHistory="true">
                        
                        </activity>
                        

                        3) 写system.exit(0) 退出应用程序。

                        【讨论】:

                        • system.exit(0) 用于退出应用程序:非常适合从 Broadcastreceiver 关闭 Activity
                        • 但这会导致不将activity历史添加到stack中,这会导致每次将activity放到后台到前台都会重新启动
                        猜你喜欢
                        • 2011-06-13
                        • 1970-01-01
                        • 2011-09-06
                        • 2012-08-20
                        • 2011-09-13
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-04-16
                        相关资源
                        最近更新 更多