Android не повторно использует основное действие и запускает несколько экземпляров (поведение только после использования PendingIntent)
У меня есть приложение только с одним действием. В onCreate я показываю уведомление, по чьему щелчку я показываю свое действие, используя его повторно при необходимости (или я так думал) Код:
package com.example.multiplestartupifusingpendingintent;
import android.app.Activity;
import android.app.Notification;
import android.app.Notification.Builder;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
public static final String TAG = "hexor";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG,
"onCreate " + getClass().getSimpleName()
+ Integer.toHexString(hashCode()));
NotificationManager notifMgr = (NotificationManager) getSystemService(Service.NOTIFICATION_SERVICE);
showReuseNotification(notifMgr);
}
private void showReuseNotification(NotificationManager notifMgr) {
Intent reuseIntent = new Intent(this, MainActivity.class);
reuseIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent reusePendingIntent = PendingIntent.getActivity(this, 2,
reuseIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(reusePendingIntent)
.setContentTitle("Resue from memory");
notifMgr.notify(2, builder.build());
}
@Override
protected void onDestroy() {
Log.d(TAG,
"onDestroy " + getClass().getSimpleName()
+ Integer.toHexString(hashCode()));
super.onDestroy();
}
}
Манифест:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.multiplestartupifusingpendingintent"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.multiplestartupifusingpendingintent.MainActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Моя проблема - это поведение, которое я не понимаю:
Если я запускаю приложение (сначала вызов onCreate), затем помещаю его в фоновый режим, затем нажимаю на значок на рабочем столе, тот же экземпляр используется повторно. В logcat я вижу только один вызов onCreate. Это то, что я хочу
Если я запускаю приложение (первый вызов onCreate), помещаю его в фоновый режим, нажимаю на уведомление, затем нажимаю значок на рабочем столе (второй вызов onCreate), затем я вижу 2 вызова onCreate в logcat. Когда я нажимаю назад, я иду дважды, прежде чем могу выйти из приложения, и обычно я вижу 2 вызова onDestroy, так как у меня есть 2 идентичных сложенных действия.
Почему происходит последнее поведение? Почему Android не использует существующее действие и создает 2 копии из них в стопке? Более странно, почему это происходит только в случае 2/ почему это не происходит также в случае 1?
Спасибо
3 ответа
В первом случае, когда вы комментируете, ваша активность приостановлена и не была уничтожена, поэтому она переходит из приостановленного состояния в возобновленное состояние. Вы можете проверить жизненный цикл действия, чтобы узнать больше об этом.
Вы должны установить
android:launchMode="singleInstance"
к вашей деятельности (в манифесте) и получать новые намерения внутри:
- onCreate (...) в случае, если деятельность была уничтожена
- onNewIntent(...) если действие приостановлено / возобновлено
Надеюсь, поможет.
Если у вас есть только один Activity
, вы должны быть в состоянии сделать это в showReuseNotification()
:
Intent reuseIntent = new Intent(this, MainActivity.class);
reuseIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent reusePendingIntent = PendingIntent.getActivity(this, 2,
reuseIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Это выведет существующий экземпляр вашего приложения на передний план (если он есть) или запустит новый (если еще нет активного).
Во втором случае ваша активность все еще видна, но не на переднем плане, потому что панель уведомлений использует способ наложения своей собственной прозрачной активности поверх второго действия, чтобы она выглядела так, как будто строка состояния опускалась на вершина деятельности.
И из-за этого особого случая Android назначает другой приоритет деятельности, лежащей в основе этой основной деятельности.
Позвольте мне найти ссылку на то, что я говорю. Я скоро вернусь.