Нарушение количества экземпляров в приложении Android Java

Я работаю над приложением для Android. Абстрактно, это приложение имеет пользовательский интерфейс для взаимодействия с пользователем, а также взаимодействует с удаленной службой. Удаленная служба добавляет уведомление на панель запуска Android, и это уведомление позволяет повторно отображать пользовательский интерфейс. Приложение и сервис находятся в одном пакете. Код функции служебного оповещения:

private void showNotification (String contentText) {
    Intent intent = new Intent (this, my_app.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
    PendingIntent pendingIntent = PendingIntent.getActivity(
            this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    mNotification = new Notification.Builder(this)
    .setContentIntent(pendingIntent)
    .setSmallIcon(ICON)
    .setWhen(System.currentTimeMillis())
    .setContentTitle(CONTENT_TITLE)
    .setContentText(contentText)
    .setAutoCancel(false)
    .setOngoing(true)
    .build();
    mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}

Примечание: это текущая версия метода... ранее я также пробовал следующие ФЛАГИ

   intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
   intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
   intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);

Манифест приложения содержит следующую конфигурацию:

    <application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:allowBackup="true"
    android:launchMode="singleTop"
    android:uiOptions="splitActionBarWhenNarrow"
    android:allowTaskReparenting="true">...</application>

Примечание. Я пробовал и другие свойства, но они не ожидали воздействия...

Когда приложение запущено, но больше не отображается, его можно повторно отобразить, используя уведомление на панели запуска или используя запись приложения в «Списке приложений», но когда я выполняю следующий сценарий, пользовательский интерфейс отображается дважды:

  1. запустить приложение из списка
  2. скотч на кнопку домой
  3. (повторно) отобразить приложение с помощью уведомления ==> пользовательский интерфейс отображается правильно
  4. скотч на кнопку домой
  5. (повторно) отобразить приложение, используя «список приложений» ==> отображается новый экземпляр пользовательского интерфейса

Логи сценария:

#start from applications list
I/ActivityManager(  504): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.domain.my_app/.My_App bnds=[40,833][200,1033]} from pid 871
I/my_app( 6915): onCreate
I/my_app::Service( 6930): onCreate
I/my_app( 6915): onResume
#tape the home button
I/my_app( 6915): onPause
#restart from notification in launcher bar
I/ActivityManager(  504): START u0 {flg=0x34400000 cmp=com.domain.my_app/.My_App bnds=[0,102][720,230]} from pid -1
I/my_app( 6915): onResume
#tape the home button
I/my_app( 6915): onPause
#start from application list
I/ActivityManager(  504): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.domain.my_app/.My_App bnds=[40,833][200,1033]} from pid 871
I/my_app( 6915): onCreate
I/my_app( 6915): onResume
#tape the home button
I/my_app( 6915): onPause
#restart from notification in launcher bar
I/ActivityManager(  504): START u0 {flg=0x34400000 cmp=com.domain.my_app/.My_App bnds=[0,102][720,230]} from pid -1
I/PSI Recorder( 6915): onResume
#it is necessary to use two times the my_app quit button in order to exit the application, and then in log, I noted the following error
E/StrictMode( 6915): class com.domain.my_app; instances=2; limit=1
E/StrictMode( 6915): android.os.StrictMode$InstanceCountViolation: class com.domain.my_app; instances=2; limit=1

Я прочитал много вещей, советов и т. д. о приложении, удаленном сервисе и уведомлении, но я не могу понять, почему пользовательский интерфейс воссоздается при перезапуске приложения из списка, и только если ранее он повторно отображался из уведомления... Примечание: если флаг FLAG_ACTIVITY_NEW_TASK не добавлен к намерению, регистрируется следующее предупреждение, и оно не меняет наблюдаемое поведение...

W/ActivityManager(  504): startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: Intent { flg=0x24400000 cmp=com.domain.my_app/.My_App bnds=[0,102][720,230] }

Я буду признателен за любую помощь.

Спасибо. С наилучшими пожеланиями,

РЕДАКТИРОВАТЬ: это моя вина, вместо поля манифеста "приложение" атрибут android:launchMode="singleTop" должен быть в элементе "активность":/

Я переехал, и это работает

    <application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:allowBackup="true">
    <activity
        android:name=".my_app"
        android:configChanges="orientation"
        android:label="@string/app_name"
        android:launchMode="singleTop"

person avf    schedule 31.05.2013    source источник


Ответы (1)


Я думаю, что источником проблемы является ваша комбинация флагов намерений. Чтобы упростить отладку, попробуйте реализовать onNewIntent() в своей активности и регистрируйте каждое полученное намерение примерно так:

protected void onNewIntent(Intent intent){
    super.onNewIntent(intent);
    Log.i("my_app", "New intent with flags "+intent.getFlags());
}

Это должно позволить вам увидеть, какие флаги вызывают второй вызов onCreate() в ваших журналах.

Что касается нарушения количества экземпляров StrictMode, я не думаю, что его стоит расследовать, как описано здесь.

ИЗМЕНИТЬ Попробуйте использовать только флаг Intent.FLAG_ACTIVITY_NEW_TASK, например, удалите три других флага. Кроме того, оставьте для android:launchMode значение singleTop.

person verybadalloc    schedule 31.05.2013
comment
Это моя вина, вместо поля ‹application› манифеста атрибут android:launchMode=singleTop должен быть в элементе ‹activity› :/ - person avf; 31.05.2013
comment
Пожалуйста, напишите это как ответ, чтобы мы могли пометить вопрос как решенный. - person verybadalloc; 31.05.2013