Android-приложение против активности

Я написал несколько приложений для Android и всегда объявлял начальный Activity как:

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Было бы замечательно ознакомиться с некоторыми глобальными методами, статикой, общими префайлами и т.д., если бы я мог запустить свое приложение, используя Application, который затем вызывает первый Activity из него onCreate() после настройки prefs и т.д. но я не смог найти примеры этого шаблона проектирования... когда я пытаюсь это сделать в коде, я получаю ClassCastException:

public class MyApplication extends Application {
@Override
    public void onCreate() {
        super.onCreate();

        // do stuff (prefs, etc)

        // start the initial Activity
        Intent i = new Intent(this, InitialActivity.class);
    startActivity(i);
    }
}

InitialActivity.class действительно является Activity, который отлично работает, если я устанавливаю его как MAIN, но попытка его запуска из MyApplication, объявленного MAIN, генерирует ошибку. Наверное, очень глупый вопрос, но решаю ли я все это неправильно?

Спасибо,

Пол

Ответ 1

Вы можете исправить это, используя флаг FLAG_ACTIVITY_NEW_TASK:

Intent intent = new Intent(this, ApplicationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Это потому, что вам нужно запустить новую задачу, когда Activity запускается вне контекста Activity. Но я настоятельно рекомендую не запускать Activity из вашего приложения onCreate().


Android имеет 4 компонента: активность, сервис, контент-провайдер и трансляция.

Когда Android должен активировать один из этих компонентов из вашего приложения, он смотрит, есть ли уже существующий процесс работы с вашим приложением. Если нет, то Android запускает новый процесс, инициализирует его, а затем инициализирует ваш собственный экземпляр приложения. И затем он активирует один из необходимых компонентов.

Теперь рассмотрим следующий сценарий: ваше приложение объявило контент-провайдера в AndroidManifest.xml, а Android как раз запустит ваше приложение, чтобы вы могли предоставить некоторые данные другому приложению переднего плана.

  • Отправляется запрос поставщика контента
  • Ваше приложение не было запущено, и Android начинает новый процесс для него.
  • Создан собственный экземпляр приложения. Вызывается
  • Application.onCreate().
  • Вы начинаете действие
  • Ваш контент-провайдер получает запрос

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

А также подумайте, нужно ли какой-либо другой активности приложения A начать действие X из вашего приложения. Но в onCreate() вы начали активность Y, а затем X также запускается Android. Затем пользователь нажимает назад. Что должно произойти? Его сложно...

Начальные действия от Application onCreate могут привести к довольно странному опыту пользователя. Так что не делайте этого.


UPDATE: Поскольку Android гарантирует, что приложение будет создано только один раз и до любого другого компонента, вы можете использовать следующий код для доступа к отдельному экземпляру приложения:

public class MyApplication extends Application 
{   
    private static MyApplication s_instance;

    public MyApplication()
    {
        s_instance = this;
    }

    public static MyApplication getApplication()
    {
        return s_instance;
    }
}

Ответ 2

Вы установили его в свой ярлык активности для этого намерения, которое вы начинаете (другое помимо основного)?

 </activity>
             <activity android:name=".InitialActivity"                          
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="com.package.INITACT" />  <--- this is only name by which you activity can be called.
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>