Android - 有时会启动错误的活动

时间:2011-07-13 01:58:33

标签: android android-activity restart

我有一个包含许多活动的Android应用程序。有时会开始错误的活动。

通常,Application子类启动,然后启动活动( StartAct ... android:name =“android.intent.action.MAIN”,android:name =“android.intent.category。 LAUNCHER“) 做一些工作,然后启动 InitializeActivity 。这会有一些工作,然后触发我的主要显示活动( MainAct )。前两个活动会执行一些必要的初始化,包括在为 MainAct 启动意图之前设置静态“ isInitialized ”标记。

使用特定意图(指定了... activity.class)使用startActivity()启动活动,并在startActivity()之后调用finish()。

然而,有时会发生这种情况,我不知道为什么......

简而言之,应用程序被终止,当按下图标启动它时,它会直接跳转到第三个( MainAct )活动。这会导致应用检测到错误( isInitialized 标志为false)并停止:

  • 使用图标正常启动应用程序:
  • ...应用程序子类启动,也会激活一些工作线程
  • ... StartActivity 运行,然后触发 InitializeActivity 并完成
  • ... InitializeActivity 运行,然后设置 isInitialized 并启动 MainAct 并完成
  • ... MainAct 启动,运行正常
  • ...主页按钮被点击,愤怒的小鸟正在运行
  • ... MainAct 记录 onPause ,然后 onStop
  • ... Application子类拥有的工作线程继续定期执行操作并记录。
  • 25分钟后,整个申请被突然杀死。这种观察是基于记录活动的结束,
  • 时间流逝
  • 主页按钮
  • 为应用程序按下了启动器ICON
  • 调用应用程序子类 onCreate 并返回
  • * MainAct.onCreate 被调用! (没有 StartAct ,没有 InitializeActivity *

我错过了什么?

注意:由于此问题,添加了initialize标志。它设置在代码中唯一开始主活动的位置,并且仅在主活动中的onCreate中进行检查。

[根据要求] 清单文件(略有编辑)。请注意,此处的服务当前未使用。

<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="xxx.yyy.zzz"
  android:versionCode="1" android:versionName="1.0.1">
  <application
    android:icon="@drawable/icon_nondistr"
    android:label="@string/app_name"
    android:name=".app.MainApp"
    android:debuggable="true">
    <activity
      android:label="@string/app_name"
      android:name=".app.StartAct" android:theme="@android:style/Theme.NoTitleBar">
      <intent-filter>
        <action
          android:name="android.intent.action.MAIN" />
        <category
          android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <activity
      android:label="Html"
      android:name=".app.HtmlDisplayAct"/>
    <activity
      android:label="Init"
      android:configChanges="orientation"
      android:name=".app.InitializeActivity" android:theme="@android:style/Theme.NoTitleBar"/>
    <activity
      android:label="MyPrefs"
      android:name=".app.PrefsAct" />
    <activity
      android:label="@string/app_name"
      android:theme="@android:style/Theme.NoTitleBar"
      android:name=".app.MainAct">
    </activity>
    <service
      android:name=".app.svcs.DataGetterService" />
  </application>
  <uses-sdk android:minSdkVersion="4"/>
  <uses-permission
    android:name="android.permission.INTERNET" />
  <uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission
    android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission
    android:name="com.android.vending.CHECK_LICENSE" />
  <uses-feature
    android:name="android.hardware.location.network"
    android:required="false" />
</manifest>

2 个答案:

答案 0 :(得分:2)

应用程序因内存不足而被杀死的事实应该对用户透明。这就是为什么当应用程序被杀死时,Android会记住这个应用程序中运行的最后一个活动是什么,并在用户返回应用程序时直接创建此活动。

也许您可以使用onCreate()(或Application)的MainAct方法执行某些操作,以确保所有内容都已正确初始化。

顺便说一句,除非你真的需要,否则当用户不使用你的应用程序时,你不应该让工作线程做一些工作。根据您的操作,这可能会快速耗尽电池,或让用户认为它可能会快速耗尽电池(更糟糕的是,因为用户将卸载您的应用程序!)

当用户退出应用程序时,您还可以让应用程序完成每个活动,

答案 1 :(得分:1)

这实际上就是“添加侮辱伤害”的情况 - 首先Android杀死了我的应用程序,然后当用户重新启动我的应用程序时,Android尝试通过启动错误的活动“有用”,导致我的应用程序崩溃。叹息。

这是我非常狡猾的解决方案来抵消Android的帮助。我的应用程序要求StartActivity必须是第一个活动,因此对于所有其他活动,我在onCreate()方法中添加一行。例如:

public class HelpActivity extends AppCompatActivity {

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      if (StaticMethods.switchToStartActivityIfNecessary(this))  return;  // <- this is the magic line

      ...

   }

  ...

}

为了完成这项工作,我在我的Application类中添加了一个switch变量:

public class OutBackClientApplication extends Application {

   ...

   // Switch to indicate if StartActivity has been started.
   // Values: -1 = StartActity has never been started or this is first invocation.
   //         0 = normal situation, StartActivity has been run at least once.
   private int _startActivityStatus = -1;

   public int getStartActivityStatus() { return _startActivityStatus; }

   public void setStartActivityStatus(int startActivityStatus) {
      _startActivityStatus = startActivityStatus;
   }

   ...

}

我有一个名为StaticMethods的类,它包含以下方法:

public class StaticMethods {

   /**
    * Method to test for the problematic situation where Android has previously killed this app, and
    * then when the user restarts the app Android tries to be helpful by restarting the activity
    * that was in the foreground when it killed the app, instead of starting the activity specified
    * in the manifest as the launch activity. See here:
    * http://stackoverflow.com/questions/6673271/android-wrong-activity-sometimes-starts
    *
    * The following line should be added to the onCreate() method of every Activity, except for
    * StartActivity, of course:
    *
    *    if (StaticMethods.switchToStartActivityIfNecessary(this))  return;
    */
   public static boolean switchToStartActivityIfNecessary(Activity currentActivity) {

      OutBackClientApplication outBackClientApplication =
                                        (OutBackClientApplication) currentActivity.getApplication();

      if (outBackClientApplication.getStartActivityStatus() == -1) {
         currentActivity.startActivity(new Intent(currentActivity, StartActivity.class));
         currentActivity.finish();
         return true;
      }
      return false;
   }

}

最后,当StartActivity启动时,需要重置开关:

 public class StartActivity extends AppCompatActivity {

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      ((OutBackClientApplication) getApplication()).setStartActivityStatus(0);

      ...

   }

   ...

}

所有这一切,只是为了抵消Android的“乐于助人”......