我有两个不同的活动。第一个启动第二个。在第二个活动中,我打电话System.exit(0)
以强制关闭应用程序,但第一个活动将自动显示,而不是应用程序返回到主屏幕。如何避免这种情况,并使应用程序返回主屏幕?
Answers:
您应该真正考虑不退出该应用程序。这不是Android应用程序通常的工作方式。
onResume
,然后再finish
进行活动。
简短的回答:呼叫moveTaskToBack(true)
你的Activity
,而不是System.exit()
。这将隐藏您的应用程序,直到用户想要再次使用它为止。
更长的答案从另一个问题开始:为什么要取消您的应用程序?
Android OS处理内存管理和进程等,因此我的建议只是让Android为您担心。如果用户想离开您的应用程序,则可以按“主页”按钮,您的应用程序将有效地消失。如果手机以后需要更多内存,则操作系统将终止您的应用程序。
只要您适当地响应生命周期事件,您和用户都不需要关心您的应用程序是否仍在运行。
因此,如果您想隐藏应用程序调用moveTaskToBack()
并让Android决定何时终止它。
下面给出实现此目的的最简单方法(不影响Android的本机内存管理。不涉及进程杀死)。
使用以下意图启动活动:
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中创建启动屏幕。这是可选的。
FinActivity
必须是您的RootActivity对吗?使用该标志将FinActivity.class
按照文档developer.android.com/reference/android/content/…中所述重新启动您。
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”,或者在启动第二个活动后立即完成第一个活动(如David所说)。
AFAIK,“强制关闭”将终止承载运行您的应用程序的JVM的进程,而System.exit()终止运行您的应用程序实例的JVM。两者都是突然终止的形式,不建议用于正常的应用程序流程。
正如捕获异常以覆盖程序可能执行的逻辑流程一样,也是不可取的。
noHistory
属性。
我使用这种方法关闭活动!
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());
,这与您通常不希望退出应用程序的方式类似。但是您可以使用它,也可以考虑研究startActivityForResult
和finishActivity
,并且仅在第二个活动以某个响应代码结束时才构建第一个活动结束的地方。
您不能执行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();
}
}
这对我来说很好。
你错了。有一种杀死应用程序的方法。在具有超类Application的类中,我们使用一些字段,例如killApp
。当启动启动屏幕(第一个活动)时onResume()
,我们将field的参数设置为false killApp
。在最后一次onResume()
调用when的每个活动中,我们都这样调用:
if(AppClass.killApp())
finish();
进入屏幕的每个活动都必须调用onResume()
。调用它时,我们必须检查我们的字段killApp
是否为真。如果为true,则当前活动调用finish()
。要调用完整动作,我们使用下一个构造。例如,在按钮操作中:
AppClass.setkillApplication(true);
finish();
return;
假设您有活动堆栈,例如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是因为,如果活动处于活动状态,它将获得启动它的第一个意图。不是新的。有关更多详细信息-文档
其实很简单。
我这样做的方法是将标记保存在所有人都可以使用的静态变量中。然后,当我退出时,设置此标志,并且我所有的活动都检查该标志onResume
。如果设置了标志,那么我将System.exit
在该活动上发出on。
这样,所有活动都将检查该标志,并且如果设置了该标志,则将正常关闭。
这是我关闭应用程序所做的事情:在我的应用程序中,我有一个基础活动类,我添加了一个称为“ applicationShutDown”的静态标志。当我需要关闭应用程序时,将其设置为true。
在调用超级调用后的基本活动onCreate和onResume中,我测试了此标志。如果“ applicationShutDown”为true,则在当前Activity上调用finish。
这为我工作:
protected void onResume() {
super.onResume();
if(BaseActivity.shutDownApp)
{
finish();
return;
}}
使用起始活动运行第二个活动以获得结果:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
//This line is important
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivityForResult(intent, REQUEST_CODE);
将此功能添加到第一个活动中:
@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);
}
不建议这样做,但是您仍然可以使用它。如果您需要退出应用程序,最好使用此解决方案。
据我说,最好的解决方案是完成应用程序中的所有活动,如下所示。
步骤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();
}
我解决了一个类似的问题: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;
看起来效果很好!:-)