Android - 如何在按下HOME键时关闭所有活动?

3

我有一个包含多个活动的应用程序。

目前,整个应用程序包含大约8个活动。首先,我展示一个闪屏屏幕几秒钟,在这里加载和设置所有偏好项(从sharedPreferences中)-这些保存在我为此制作的“Setting”类中 - 这个类基本上只有一堆静态变量,所以应用程序中的所有活动都可以读取这些变量,并根据需要进行修改。

编辑:随着应用程序运行,更多的数据将存储在此类中,其中一些来自Web服务 - 数据被解析为对象,并将对这些对象的引用也保存在Settings类中(或对象列表)。

我的问题是,当用户按HOME键时,当前活动将被放入后台。如果活动长时间在后台(很多用户通过按home而不是back键来“关闭”应用程序),然后重新打开它,它会显示在HOME键被按下之前正在运行的活动。

例如-假设用户启动应用程序,看到闪屏屏幕几秒钟。然后闪屏屏幕启动一个新活动并在其上调用finish。

这意味着现在活动堆栈只有MainActivity(主菜单)。在MainActivity中,我在onCreate方法中为所有按钮提供侦听器,大多数按钮都需要来自上述Settings类的一些信息。

然后当我按HOME并几个小时后重新打开应用程序时,所有按钮都无效了-似乎图形正在反应等,但仍然出现某些问题。其中一个即使所有设置被清除也应该工作的按钮只会打开带有一些文本的对话框。

侦听器:

Button b = (Button)v.findViewById(R.id.id_b1);
b.setOnClickListener(new OnClickListener() {
  public void onClick(View v) {
    Dialog dialog = createDialog(MainActivity.this, DIALOG_CONST1);
    dialog.show();
  }
});

我有一些对话框类型的常量,由于我正在使用一些自定义设计来创建对话框,因此我创建了一个类来为我创建对话框。

从包含按钮的活动(稍微简化一下):

public static Dialog createDialog(final Context c, int dialogId) {
  Dialog dialog = null;
  CustomDialog.Builder customBuilder;
  switch (dialogId) {
    ...
    case d1:
      customBuilder = new CustomDialog.Builder(c, DIALOG_CONST1);

      //Sets up the parapters to create the dialog afterwards
      customBuilder.setTitle("Header").setMessage("Content")
      .setPositiveButton("", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
          dialog.dismiss();
        }
      });
      dialog = customBuilder.create(); //Creates the dialog from the above settings
      dialog.setCanceledOnTouchOutside(true);
      break;
    ...
  }
  ... //Set the width of the dialog
  return dialog;
}

CustomDialog类继承了Dialog类,然后根据提供的常量之一来填充多个对话框布局并添加内容等。通常情况下运行良好,但在应用程序被HOME暂停一段时间后,当我按下按钮时不会显示任何对话框。我看到其他按钮上有一个加载对话框的闪烁,但之后什么也没有发生 - 没有显示对话框。奇怪的是,如果我再次在屏幕中间按下按钮,则无法按下它(图形不会反应),但是当我先在屏幕侧面按下一次,然后再在中间按下时,图形会反应,对话框在按下外部时会被取消,因此我想知道是否存在一些非常薄的“透明”对话框或其他问题 - 我真的不知道为什么会发生这种情况。
编辑:实际上,在查看Settings类中保存的变量时,我发现我确实保存了屏幕的宽度和高度(以像素为单位)。将宽度设置为屏幕宽度的某个百分比用于设置自定义对话框的宽度。如果设置被删除,那么宽度被设置为0可能解释了为什么我看不到任何对话框... 如果不是所有我的Settings类中的变量都被删除,我真的无法弄清楚发生了什么 - 一切似乎都指向这一点。
dialog.getWindow().setLayout(Settings._widthpx - (Settings._widthpx/5), dialog.getWindow().getAttributes().height); //Width = 80%

实际上我必须承认,我对Android还比较新手,不太清楚是什么导致了这个问题。我怀疑当Settings类没有被使用时,GC会在一段时间后删除所有变量,导致用户几个小时后返回时所有设置都被清除。但这并不能解释为什么按钮不起作用(其中一个按钮不需要设置)。
这个主要活动可以启动其他活动,这些活动又可以启动新的活动。
我认为,如果我能强制在HOME键按下时关闭整个应用程序,那么我的所有问题都可以得到解决,并在下次点击应用图标时强制重新启动应用程序-从而强制监听器和设置加载。
我在这里阅读了关于“android:clearTaskOnLaunch”,“android:launchMode”和“android:finishOnTaskLaunch”的内容,但我不太确定如何正确使用它们。
请有人能向我解释为什么按钮不起作用,或者当应用程序长时间处于后台时Settings类中的变量可能发生的情况,或者给我一些关于如何正确使用“activity”设置的好提示。
编辑:该应用程序将运行Android 1.6+,因此我无法使用任何更新的功能或其他东西...
非常感谢。

根据您想要的设置数据结构类型,您最好使用SharedPreferences类。(http://developer.android.com/guide/topics/data/data-storage.html#pref) 看起来未捕获的按钮有点神秘。能否贴出创建它/设置监听器的代码? - Turnsole
当我在启动屏幕期间加载设置时,我从sharedPreferences中加载设置,因此我已经尽可能地使用了这些设置。但是,我还从Web服务器获取一些数据,将其解析为对象,并直接将引用保存在Settings类中或包含它们的列表中。我可以通过尽可能多地使用sharedPreferences来解决部分问题,但似乎仍然会清除从Web服务解析的对象。还有一个评论... - Knirkegaard
关于按钮和监听器 - 我将编辑原始帖子中的代码,但是我刚从工作回来时尝试了一下,启动应用程序并按Home键,然后在回家时打开。字体设置为标准,并且一个按钮会出现错误,指示用户名(从sharedPrefs读取并在运行时保存在Settings类中)已设置为null(被清除)。监听器确实起作用(我的错)-我将编辑原始帖子以解释发生了什么。 - Knirkegaard
5个回答

3
  • 不要覆盖主页键的功能。也许您会在某个地方找到某些东西,使您能够这样做。一个尊重标准的应用程序绝不会以任何方式覆盖主页键。
  • 只需将 android:clearTaskOnLaunch=true 放入您的清单中即可。这将确保每次按下启动器图标时都会启动您的主活动。

我怀疑当“Settings”类未被使用时,GC会在一段时间后删除所有变量-导致用户在几个小时后返回时所有设置都被清除

  • Android并没有对您的应用程序这样作恶。它可能会在一段时间的不活动和/或需要更多内存之后杀死您的应用程序、服务和后台运行的任何东西,但绝不会让您的应用程序无法正常运行且没有变量。

我并不试图以任何方式覆盖 HOME 按钮(我读到这应该永远不会这样做),我只是在寻找一种方法,每当单击应用程序图标时从启动器(加载设置)启动应用程序。我不确定我的 Settings 类中的引用发生了什么(仅包含静态变量和方法),但在主屏幕上停留一段时间然后再次打开应用程序后,它们似乎消失了 - 我不知道这是如何发生的。 但是,只有在它隐藏了一段时间后才会发生此情况(在回家的路上尝试过,30 分钟后它就会发生)。 如果只有 1 分钟 - 一切都正常。 - Knirkegaard
看一下我刚刚做的修改 - 不确定是不是只有我自己想的,但我认为我看到的所有错误都可能是由于在设置类中缺少变量所致。 - Knirkegaard

0

为了后人,我在我的应用程序中在 onStop() 方法中添加了 finish(); ,在我完成所有操作后它非常有效。


0

我实际上是为 Android 2.0 开发进行了定制,现在可能有更好的选择。我的做法是将所有活动声明为全局变量,当您从任何地方单击主页按钮时,我们会检查它们是否不为空。如果不为空,则关闭它们并将引用设置为 null。这些活动仅在全局范围内声明,只有在需要使用它们时才定义。


应用程序必须在Android 1.6+上运行,因此不可以使用2.0的东西。谢谢。 - Knirkegaard

0

如果您使用的是Android 4.0或更高版本,您可以在开发者选项中启用“不保留活动”功能。如果您没有4.0设备,则可以使用模拟器。


该应用程序必须在Android 1.6+上运行,因此使用在较新版本中实现的功能不是一个选择。谢谢。 - Knirkegaard
我认为导致应用在后台运行一段时间后崩溃的原因很可能在4.0或1.6中是相同的,因此在4.0中修复它可能会同时解决1.6中的问题。 - Gallal

0

你需要杀死所有在主屏幕按钮上方的当前活动,并且为此你需要重写Home键功能,其中你需要编写以下内容:

Intent intent = new Intent(context,login.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

这将清除在按下主页键并切换到登录活动的顶部活动上的所有活动,

如果您不想覆盖主页键功能,则只需在Androidmanifest.xml中编写一个即可,即android:clearTaskOnLaunch=true,从此每当您单击应用程序图标时,它都会启动您的第一个活动

我建议采用第二种方法最适合您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接