Android - при запуске одного и того же действия из виджета с разными дополнениями, как предотвратить появление одного и того же экземпляра после возврата с кнопки HOME?

У меня есть виджет, который содержит 4 кнопки для отображения 4 цен на акции, каждая из которых запускает одно и то же действие Quote.class для отображения сведений об акциях. В onUpdate() он установит pendingIntent с дополнительными функциями с символом акции. После того, как я нажму кнопку A, он перейдет к действию Quote, которое показывает акции A. Затем я нажму кнопку BACK на домашний экран, действие Quote вызовет onDestroy(), и когда я нажму кнопку B, акции B отобразятся правильно. Однако, когда я нажимаю кнопку HOME после того, как она показывает акцию A, активность Quote вызывает только onStop без вызова onDestroy(), затем, когда я нажимаю кнопку B, она вызывает onStart() и показывает тот же экземпляр, что показывает акцию A.

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.etappwidget); 
setQuoteIntent(context, views, R.id.view1, "BAC", 1);
setQuoteIntent(context, views, R.id.view2, "C", 2);
setQuoteIntent(context, views, R.id.view3, "GOOG", 3);
setQuoteIntent(context, views, R.id.view4, "AAPL", 4);

 private static void setQuoteIntent(Context context, RemoteViews views, int viewId, String symbol, int requestCode) {
 Intent i = new Intent(context, Quote.class);
 i.putExtra("SYMBOL", symbol);
 i.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
 PendingIntent pi = PendingIntent.getActivity(context, requestCode, i, PendingIntent.FLAG_UPDATE_CURRENT);
 views.setOnClickPendingIntent(viewId, pi);

}

Первоначально я думал, что добавление флага в Intent должно решить эту проблему. Но я пробовал i.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK или FLAG_ACTIVITY_NEW_TASK или FLAG_ACTIVITY_NO_HISTORY), ни один из них не имеет никакого значения.

Так есть ли способы заставить его работать? Как я могу удалить стек истории с кнопки HOME? Как я могу вызывать onCreate в Quote и получать новые дополнения, когда нажимаю кнопку B? Любая помощь приветствуется. Спасибо


person nickyfantasy    schedule 05.11.2010    source источник


Ответы (5)


  • Это нормально, что onDestroy может не вызываться, если вы выполняете простое переключение задач (например, удерживаете кнопку HOME). Если вам нужно сделать очистку, это нужно сделать в onPause.
  • Я считаю, что проблема в том, что у вас есть PendingIntent, который отличается только дополнительным. PendingIntents кэшируются, поэтому, если вы используете два с одинаковым действием и данными, они перезапишут друг друга. Вы можете обойти это, предоставив каждому несколько случайных данных. Попробуйте передать символ в данных, а не через дополнительные (что в любом случае предпочтительнее).
person EboMike    schedule 05.11.2010
comment
Как именно я должен передавать данные? Вы имеете в виду использование метода намерения.setData(Uri uri)? - person nickyfantasy; 05.11.2010
comment
да. Создайте свой собственный простой Uri для акций. - person EboMike; 05.11.2010
comment
Это работает для случайных данных? Мой способ избежать кеширования ожидающих намерений — использовать разные имена намерений для разных кнопок/виджетов. - person xandy; 06.11.2010
comment
Мне также пришлось сделать дополнительный шаг, вызвав setIntent(intent) в методе onNewIntent() моего класса Activity. - person Chris Knight; 01.11.2011

Вы можете попробовать это:

        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);

Ваша активность не будет отображаться в стеке истории

person user479211    schedule 05.11.2010

clickIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

Начиная с: API уровня 1. Если установлено, новое действие не сохраняется в стеке истории. Как только пользователь уходит от него, действие завершается. Это также можно установить с помощью атрибута noHistory.

Это решило ту же проблему, что и моя, при реализации действий с виджетами.

person Atrinax    schedule 11.03.2012

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

person xandy    schedule 05.11.2010
comment
Я уже пробовал вызывать getIntent().getStringExtra(Symbol) в onResume вместо onCreate. Тем не менее, он по-прежнему будет получать символ A каждый раз, когда я нажимаю другие кнопки в виджете. Похоже, там останется та же лишняя. Можно ли как-то заменить новый доп? Должен ли я что-нибудь сделать в onStop (), может быть? - person nickyfantasy; 05.11.2010

Если вы используете другое действие в своем намерении и используете флаг SingleTop или аналогичный и переопределяете onNewIntent, чтобы определить правильное действие, которое должно сработать. Вы должны быть готовы обрабатывать намерение в onCreate и onNewIntent.

person Nathan Schwermann    schedule 05.11.2010