我有两个不同的活动。第一个启动第二个。在第二个活动中,我调用System.exit(0)
以强制关闭应用程序,但第一个活动会自动显示,而不是应用程序返回主屏幕。我怎样才能避免这种情况,并让应用程序返回主屏幕?
21 回答
简短的回答:调用moveTaskToBack(true)
你的Activity
而不是System.exit()
. 这将隐藏您的应用程序,直到用户想要再次使用它。
更长的答案从另一个问题开始:你为什么要杀死你的应用程序?
Android 操作系统处理内存管理和进程等,所以我的建议是让 Android 为您担心这些。如果用户想离开您的应用程序,他们可以按 Home 按钮,您的应用程序将有效地消失。如果手机稍后需要更多内存,操作系统将终止您的应用程序。
只要您适当地响应生命周期事件,您和用户都不需要关心您的应用程序是否仍在运行。
因此,如果您想隐藏您的应用程序调用moveTaskToBack()
并让 Android 决定何时终止它。
下面给出了实现这一点的最简单方法(不影响 Android 的本机内存管理。不涉及进程终止)。
使用这个 Intent 启动一个活动:
Intent intent = new Intent(this, FinActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish();
在目标活动
FinActivity.class
中,调用finish()onCreate
。
步骤说明:
您创建一个删除所有其他活动
(FLAG_ACTIVITY_CLEAR_TOP)
并删除当前活动的意图。活动会自我毁灭。另一种方法是您可以在 finActivity 中制作启动画面。这是可选的。
你真的应该考虑不退出应用程序。这不是 Android 应用程序通常的工作方式。
Android 有一种机制可以根据其文档安全地关闭应用程序。在退出的最后一个 Activity(通常是应用程序启动时首先出现的主 Activity)中,只需在 onDestroy() 方法中放置几行。对System.runFinalizersOnExit(true)的调用可确保在应用程序退出时所有对象都将被终结并被垃圾收集。例如:
public void onDestroy() {
super.onDestroy();
/*
* Notify the system to finalize and collect all objects of the
* application on exit so that the process running the application can
* be killed by the system without causing issues. NOTE: If this is set
* to true then the process will not be killed until all of its threads
* have closed.
*/
System.runFinalizersOnExit(true);
/*
* Force the system to close the application down completely instead of
* retaining it in the background. The process that runs the application
* will be killed. The application will be completely created as a new
* application in a new process if the user starts the application
* again.
*/
System.exit(0);
}
最后,Android 不会通知应用程序HOME键事件,因此当按下HOME键时您无法关闭应用程序。Android 将 HOME键事件保留给自己,以便开发人员无法阻止用户离开他们的应用程序。
您还可以在第一个活动的标签中指定noHistory = "true" 或在您开始第二个活动后立即完成第一个活动(如大卫所说)。
AFAIK,“强制关闭”会终止托管您的应用程序运行所在的 JVM 的进程,并且 System.exit() 会终止运行您的应用程序实例的 JVM。两者都是突然终止的形式,不建议用于正常的应用程序流程。
正如捕获异常以覆盖程序可能执行的逻辑流一样,也不可取。
我用这个方法来关闭Activity!
public static void closeAllBelowActivities(Activity current) {
boolean flag = true;
Activity below = current.getParent();
if (below == null)
return;
System.out.println("Below Parent: " + below.getClass());
while (flag) {
Activity temp = below;
try {
below = temp.getParent();
temp.finish();
} catch (Exception e) {
flag = false;
}
}
}
当您启动第二个活动时,finish()
第一个活动立即:
startActivity(new Intent(...));
finish();
android.os.Process.killProcess(android.os.Process.myPid());
工作正常,但建议让Android平台担心内存管理:-)
你不能做 System.exit(),它不安全。
你可以这样做: Process.killProcess(Process.myPid());
我用这个:
1) 父活动调用辅助活动,方法为“startActivityForResult”
2)在关闭时的辅助活动中:
int exitCode = 1; // Select the number you want
setResult(exitCode);
finish();
3)并在父活动中覆盖方法“onActivityResult”:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
int exitCode = 1;
if(resultCode == exitCode) {
super.setResult(exitCode); // use this if you have more than 2 activities
finish();
}
}
这对我来说很好。
使用finish
方法。这是更简单、更容易的方法。
this.finish();
你错了。有一种方法可以杀死应用程序。在具有超类 Application 的类中,我们使用一些字段,例如killApp
. 当我们在 中启动启动画面(第一个活动)时onResume()
,我们为 field 设置了一个参数为 false killApp
。在最后调用的每个活动中onResume()
,我们调用类似的东西:
if(AppClass.killApp())
finish();
每个进入屏幕的活动都必须调用onResume()
。当它被调用时,我们必须检查我们的字段killApp
是否为真。如果是真的,当前活动调用finish()
. 为了调用完整的动作,我们使用下一个构造。例如,在按钮的操作中:
AppClass.setkillApplication(true);
finish();
return;
试试下面的。这个对我有用。
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
am.restartPackage(componentInfo.getPackageName());
使用 startActivityForResult 启动第二个活动,并在第二个活动中返回一个值,一旦在第一个活动的 onActivityResult 方法中关闭主应用程序。我认为这是 Android 的正确做法。
假设您有 A>B>C>D>E 之类的活动堆栈。你在活动 D,你想关闭你的应用程序。这就是你要做的——
在要关闭的活动中(活动 D)-
Intent intent = new Intent(D.this,A.class);
intent.putExtra("exit", "exit");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
在您的 RootActivity(即您的基本活动,此处为活动 A)中 -
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent.hasExtra("exit")) {
setIntent(intent);
}
}
@Override
protected void onResume() {
super.onResume();
if (getIntent() != null) {
if (("exit").equalsIgnoreCase(getIntent().getStringExtra(("exit")))) {
onBackPressed();
}
}
}
使用 onNewIntent 是因为如果活动处于活动状态,它将获得启动它的第一个意图。不是新的。有关更多详细信息 -文档
请记住,在处理使用持久套接字连接的应用程序时,该finish()
方法不会释放连接。在正常情况下,finish()
是最好的选择,但如果你绝对需要退出一个应用程序并释放它正在使用的所有资源,那么使用killProcess
. 我使用它没有任何问题。
这是我关闭应用程序所做的:在我的应用程序中,我有一个基本活动类,我添加了一个名为“applicationShutDown”的静态标志。当我需要关闭应用程序时,我将其设置为 true。
在调用超级调用后的基本活动 onCreate 和 onResume 中,我测试了这个标志。如果“applicationShutDown”为真,我会在当前 Activity 上调用完成。
这对我有用:
protected void onResume() {
super.onResume();
if(BaseActivity.shutDownApp)
{
finish();
return;
}}
它实际上很容易安静。
我这样做的方法是在所有人都可以使用的静态变量中保存一个标志。然后,当我退出时,我设置了这个标志,我的所有活动都会检查这个标志onResume
。如果设置了标志,那么我会System.exit
在该活动上发出。
这样,所有活动都将检查标志,如果设置了标志,则会正常关闭。
不推荐,但您仍然可以使用它。如果您需要退出应用程序,最好使用此解决方案。
根据我的说法,最好的解决方案是完成您应用中的所有活动,如下所示。
步骤 1. 在 mainactivity 中维护一个静态变量。说,
public static boolean isQuit = false;
步骤 2. 在按钮的单击事件中,将此变量设置为 true。
mainactivity.isQuit = true;
finish();
第 3 步。在您的应用程序的每个活动中,使用以下onrestart
方法。
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
if(mainactivity.isQuit)
finish();
}
使用 start 活动运行第二个活动以获得结果:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
//This line is important
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivityForResult(intent, REQUEST_CODE);
将此函数添加到第一个 Activity:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(rquestCode == REQUEST_CODE)
if(resultCode == RESULT_CANCELED)
finish();
}
并将其添加到第二个活动中:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
Log.i(TAG, "Back key pressed");
setResult(RESULT_CANCELED);
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
我解决了一个类似的问题:MainActivity 启动 BrowserActivity,当用户在 BrowserActivity 中按下 Back 时,我需要关闭应用程序 - 而不是在 MainActivity 中返回。因此,在 MainActivity 中:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "sm500_Rmt.MainActivity";
private boolean m_IsBrowserStarted = false;
然后,在 OnResume 中:
@Override
protected void onResume() {
super.onResume();
if(m_IsBrowserStarted) {
Log.w(TAG, "onResume, but it's return from browser, just exit!");
finish();
return;
}
Log.w(TAG, "onResume");
...然后继续 OnResume。并且,当启动 BrowserActivity 时:
Intent intent = new Intent(this, BrowserActivity.class);
intent.putExtra(getString(R.string.IPAddr), ip);
startActivity(intent);
m_IsBrowserStarted = true;
而且看起来效果很好!:-)