Je démarre un service (ou redémarre le service en cours d'exécution) lorsqu'une activité est lancée, en utilisant:
Intent intent = new Intent(this, MyService.class);
startService(intent);
Ensuite, en fonction de certaines actions, la même activité est liée au service à l’aide de
bindService(new Intent(this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
Et quand l'activité est détruite, j'appelle
unbindService(mConnection);
Auparavant, le service redémarrait lorsque j'avais tué la même activité/application dans la barre des tâches et affiché le message "Processus 1 du service 1 en cours d'exécution" dans les applications en cours d'exécution.
Désormais, le service ne redémarre pas lorsque vous supprimez la même activité/application.
Et je reçois le message "0 processus 1 service en cours d'exécution" , ce qui signifie que le service n'est pas en cours d'exécution.
Le service ne redémarre pas à la fermeture de l'application. Mon application consiste en une activité. De plus, le service est démarré avec succès lorsqu'il est lancé après un démarrage du système.
Pourquoi le processus du service est-il tué quand je le lance en utilisant startService () ??
modifier
Le service avait l'habitude de redémarrer plus tôt après la fermeture de l'application à partir du volet Applications. Mais maintenant, avec le code SAME, ce n’est pas le cas. Cela arrive aussi avec d'autres applications quand je les ferme. par exemple.
Voici une solution de contournement que j'ai découverte et qui fonctionne bien pour relancer un service si son processus est tué à la fermeture de l'application. Dans votre service, ajoutez le code suivant.
Je suis tombé sur cette solution de contournement dans this thread.
@Override
public void onTaskRemoved(Intent rootIntent){
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartServicePendingIntent);
super.onTaskRemoved(rootIntent);
}
Semble être un bogue que le processus de l'application est tué. Il est inutile qu'un service s'exécute si son processus est tué.
S'il vous plaît être conscient de cela: onDestroy n'est pas toujours appelé. Vous ne devriez pas mettre le code de cette façon.
Lorsque l'activité est forcée fermée ou fermée de manière anormale par le système, onDestroy n'est pas appelé.
Malheureusement, il s’agit d’un problème compliqué en raison du fonctionnement d’Android. Il existe un certain nombre de stratégies qui traitent chacune différentes parties du problème. Pour de meilleurs résultats, combinez plusieurs stratégies.
Notez que certaines de ces stratégies peuvent ne plus être nécessaires dans les versions plus récentes d'Android.
Déconnecté de Service de premier plan tué lors de la réception d'une émission après qu'une activité a été balayée dans la liste des tâches :
Au premier plan du service:
@Override public void onTaskRemoved( Intent rootIntent ) { Intent intent = new Intent( this, DummyActivity.class ); intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK ); startActivity( intent ); }
Dans le manifeste:
<activity Android:name=".DummyActivity" Android:theme="@Android:style/Theme.NoDisplay" Android:enabled="true" Android:allowTaskReparenting="true" Android:noHistory="true" Android:excludeFromRecents="true" Android:alwaysRetainTaskState="false" Android:stateNotNeeded="true" Android:clearTaskOnLaunch="true" Android:finishOnTaskLaunch="true" />
(Si votre service est dans un processus différent, définissez le processus de cette activité sur le même processus.)
Dans DummyActivity.Java:
public class DummyActivity extends Activity { @Override public void onCreate( Bundle icicle ) { super.onCreate( icicle ); finish(); } }
Provoque la fermeture de l'activité récente. Normalement, balayer une application ne ferme pas l'activité récente.
Cela ne prend effet que lorsque l'activité fictive démarre , ce qui peut prendre une demi-seconde ou plus, de sorte que le service risque toujours d'être tué un instant.
Lorsque vous supprimez/balayez votre application, un indicateur appelé waitingToKill
est set . Lorsque cet indicateur est défini, Android peut interrompre le processus à tout moment dans le futur , tel que lorsque vous recevez une émission . Commencer une activité efface ce drapeau.
BroadcastReceiver
with retransmissions au premier planFusionner ceci dans votre code de service:
if (Build.VERSION.SDK_INT >= 16) {
Intent intent = new Intent(this, DummyReceiver.class);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
//This seems to be timing-related; the more times we do this,
//the less likely the process gets killed
for (int i = 0; i < 50; ++i)
sendBroadcast(intent);
}
Créez un récepteur de diffusion factice:
public class DummyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {}
}
Ajoutez le destinataire à votre manifeste:
<receiver Android:name=".DummyReceiver" />
Peut provoquer un léger retard (~ 250 ms)/blocage lorsque la tâche est supprimée de l'écran Récents.
Cela ne fait que maintenir le processus en cours pendant la réception des émissions. the waitingToKill
flag est toujours défini sur, de sorte que le processus peut toujours être supprimé par la suite, par exemple lors de la réception d'une émission.
Si votre processus ne fonctionne pas en priorité au premier plan, Android essaiera de le tuer immédiatement . La réception d’émissions de premier plan l’empêche temporairement, ce qui entraîne la définition de l’indicateur waitingToKill
.
Je sais que cette question est ancienne, mais j'ai récemment rencontré ce problème et, tout à coup, mon service s'est arrêté lors de la fermeture de l'application. Auparavant, cela fonctionnait bien. Ce problème m'a fait perdre beaucoup de temps. Si vous rencontrez des problèmes similaires, assurez-vous que VOTRE RESTRICTION DE DONNÉES DE FOND IS est désactivé . C’est le problème que j’ai eu et cela a du sens car lorsque le traitement des données en arrière-plan est restreint, le processus en arrière-plan restreint ne sera pas exécuté.
onDestroy n'est pas toujours appelé. Le principal problème dans votre cas est votre impossibilité de démarrer le service à la fermeture de l'application. Android OS ( Dans Certains OS ) tuera le service. Si vous ne parvenez pas à redémarrer le service, appelez une alarme. crèche pour démarrer le reciver comme ça,
Manifeste est,
<service
Android:name=".BackgroundService"
Android:description="@string/app_name"
Android:enabled="true"
Android:label="Notification" />
<receiver Android:name="AlarmReceiver">
<intent-filter>
<action Android:name="REFRESH_THIS" />
</intent-filter>
</receiver>
IN Main Activty lance le gestionnaire d’alarmes de cette manière,
String alarm = Context.ALARM_SERVICE;
AlarmManager am = (AlarmManager) getSystemService(alarm);
Intent intent = new Intent("REFRESH_THIS");
PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);
int type = AlarmManager.RTC_WAKEUP;
long interval = 1000 * 50;
am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);
cela appellera reciver et reciver est,
public class AlarmReceiver extends BroadcastReceiver {
Context context;
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
System.out.println("Alarma Reciver Called");
if (isMyServiceRunning(this.context, BackgroundService.class)) {
System.out.println("alredy running no need to start again");
} else {
Intent background = new Intent(context, BackgroundService.class);
context.startService(background);
}
}
public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
if (services != null) {
for (int i = 0; i < services.size(); i++) {
if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
return true;
}
}
}
return false;
}
}
Et ce récepteur Alaram appelle une fois lorsque l'application Android est ouverte et lorsque l'application est fermée. Le service est ainsi,
public class BackgroundService extends Service {
private String LOG_TAG = null;
@Override
public void onCreate() {
super.onCreate();
LOG_TAG = "app_name";
Log.i(LOG_TAG, "service created");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOG_TAG, "In onStartCommand");
//ur actual code
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// Wont be called as service is not bound
Log.i(LOG_TAG, "In onBind");
return null;
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(LOG_TAG, "In onTaskRemoved");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "In onDestroyed");
}
}