Android - иногда начинается неправильная активность - PullRequest
5 голосов
/ 13 июля 2011

У меня есть приложение для Android с целым рядом мероприятий. Иногда начинается неправильная деятельность.

Обычно подкласс приложения запускается, затем запускается действие ( StartAct ... android: name = "android.intent.action.MAIN", android: name = "android.intent.category.LAUNCHER «) выполняет некоторую работу, а затем запускает InitializeActivity . Это делает некоторую работу, а затем запускает мой основной экран ( MainAct ). Первые два действия выполняют некоторую существенную инициализацию, включая установку статического флага " isInitialized " непосредственно перед запуском намерения для MainAct .

Операции запускаются с помощью startActivity () с использованием определенного намерения (... определен класс Activity.class) и вызывают finish () после startActivity ().

Однако вот что иногда случается, и я не знаю почему ...

Короче говоря, приложение убивается, и при нажатии на значок, чтобы запустить его, оно переходит прямо к третьему ( MainAct ) действию. Это приводит к тому, что приложение обнаруживает ошибку ( isInitialized флаг имеет значение false) и останавливается:

  • Запустите приложение как обычно с помощью иконки:
  • ... Подкласс приложения запускается, также запускаются некоторые рабочие потоки
  • ... StartActivity запускается, затем запускается InitializeActivity и завершается
  • ... InitializeActivity запускается, затем устанавливает isInitialized и запускает MainAct и завершает
  • ... MainAct запускается, работает нормально
  • ... Нажата кнопка «Домой» и запущены Angry Birds
  • ... MainAct logs onPause , затем onStop .
  • ... Рабочие потоки, принадлежащие подклассу Application, продолжают периодически делать вещи и регистрироваться.
  • Через 25 минут все приложение внезапно убивается. Это наблюдение основано на окончании лесозаготовительных работ,
  • Время идет
  • Нажатие кнопки Home
  • Кнопка запуска запускается для приложения
  • Подкласс приложения onCreate вызывается и возвращает
  • * MainAct.onCreate вызывается! (нет StartAct , нет InitializeActivity ) *

Чего мне не хватает?

Примечание. Из-за этой проблемы был добавлен флаг инициализации. Он устанавливается в единственном месте в коде, который запускает основное действие, и проверяется только в 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 ]

2 голосов
/ 13 июля 2011

Тот факт, что приложение убито из-за нехватки памяти, должно быть прозрачным для пользователей.Вот почему, когда приложение убито, Android запоминает, что было последним действием, запущенным в этом приложении, и создает непосредственно это действие, когда пользователь возвращается в приложение.

Возможно, вы могли бы что-то сделать в onCreate()метод вашего Application (или вашего MainAct), чтобы убедиться, что все правильно инициализировано.

Кстати, если вам действительно не нужно, рабочие потоки не должны выполнять какую-то работу, когдапользователь не использует ваше приложение.В зависимости от того, что вы делаете, это может быстро разрядить батарею или заставить пользователя думать, что она может быстро разрядить батарею (что еще хуже, поскольку пользователь удалит ваше приложение!)

Вы также можете сделать приложениезавершить все действия, когда пользователь выходит из приложения,

1 голос
/ 30 апреля 2017

Это действительно «добавление оскорбления к травме» - сначала 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

      ...

   }

  ...

}

Чтобы сделать это, я добавил переменную switch в свой класс Application:

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:
    * /7276315/android-inogda-nachinaetsya-nepravilnaya-aktivnost
    *
    * 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 ...

...