J'ai récemment remplacé tous mes services de services de premier plan et JobIntentService, car il existe certaines limites d'exécution en arrière-plan ( https://developer.Android.com/about/versions/oreo/background ) dans OREO et les versions ultérieures. Conformément à la documentation, JobIntentService agit comme Intent Service pour Android 7 et versions antérieures et comme JobScheduler pour Android 8 et versions ultérieures. J'ai remarqué un problème dans le nouveau JobIntentService fourni par Google.
Android 8 et supérieur:
Un crash se produit continuellement dans Android 8 et supérieur. Il y avait un ticket soulevé ici mentionnant à propos du même problème https://issuetracker.google.com/issues/63622293 et j'ai ajouté un correctif temporaire suggéré par quelques geeks.
Android 7 & ci-dessous: JobIntentService qui agit comme si Intent Service n'était pas arrêté une fois le travail terminé.
J'ai implémenté JobIntentService dans un service qui se déclenche chaque fois qu'une action est effectuée par un utilisateur.
Code
public class SampleJobIntentService extends FixedJobIntentService {
public static void postData(Context context, String data) {
Intent intent = new Intent(context, SampleJobIntentService.class);
intent.setAction(INITIAL_ACTION);
intent.putExtra(SAMPLE_ID, data);
SampleJobIntentService.enqueueWork(context,intent);
}
public static void enqueueWork(Context context, Intent work) {
SampleJobIntentService.enqueueWork(context, SampleJobIntentService.class, JOB_ID, work);
@Override
protected void onHandleWork(@NonNull Intent intent) {
if (intent != null) {
SampleRequest sampleRequest = requests.get(intent.getAction());
if (sampleRequest != null) {
try {
// perform some networking operations
} catch (Exception ex) {
Log.d("Error for intent ");
}
Log.i("send action ");
} else
Log.e("action not found for ");
}
}
}
Pour éviter le blocage avec JobIntentService, j'ai pris quelques références de https://issuetracker.google.com/issues/63622293
public abstract class FixedJobIntentService extends JobIntentService {
@Override
GenericWorkItem dequeueWork() {
try {
return new FixedGenericWorkItem(super.dequeueWork());
} catch (SecurityException ignored) {
doStopCurrentWork();
}
return null;
}
private class FixedGenericWorkItem implements GenericWorkItem {
final GenericWorkItem mGenericWorkItem;
FixedGenericWorkItem(GenericWorkItem genericWorkItem) {
mGenericWorkItem = genericWorkItem;
}
@Override
public Intent getIntent() {
if (mGenericWorkItem != null) {
return mGenericWorkItem.getIntent();
}
return null;
}
@Override
public void complete() {
try {
if (mGenericWorkItem != null) {
mGenericWorkItem.complete();
}
} catch (IllegalArgumentException ignored) {
doStopCurrentWork();
}
}
}
}
Eh bien ..., c'est beaucoup une grande théorie ... !! Il ne serait pas capable de tout mettre ici. Je ferai de mon mieux pour que vos concepts soient clairs.
J'ai déjà perdu mes deux années complètes dans la lecture de documentations sur Google ... Ce sont use-less
... Avec no proper documentation
et avec no proper sample codes for its developers
.. !! Donc, je mentionne cela dans chacun de mes messages sur stack-overflow
, car cela aidera à gagner du temps pour les autres .. !!
Il semble que vous soyez un bon programmeur. juste besoin de hints to your posted question
:
Astuce-1:
VOUS: - J'ai récemment remplacé tous mes services de services de premier plan et JobIntentService
service de premier plan:
Si vous avez besoin de ALL THE TIME RUNNING PROCESS; WHICH WILL NEVER END... ONCE IT IS STARTED
, il est utilisé dans le service qui renvoie START_STICKY
à partir de sa OnStartCommand
. Encore une fois, il est déconseillé de l'utiliser comme si vous vouliez l'implémenter à tout prix ... vous devrez alors utiliser une notification avec setOngoing(true)
Quel utilisateur final ne pourrait pas effacer votre notification, elle y restera indéfiniment .. ..
Utilisation du service de premier plan:
Il y a eu aussi des restrictions sur les destinataires; ci-dessus Oreo
et vous ne pouvez pas utiliser tous les destinataires et actions d'intention en le déclarant dans un manifeste et en créant simplement un destinataire ... Je vous conseille d'utiliser simplement la permission BootComplete
et d'utiliser un seul receiver
qui reçoit le boot_completed
intention et appelle un service
si en dessous de O et appelle un service de premier plan au-dessus de O. Maintenant, à partir de ce service de premier plan, vous implémentez les récepteurs d'exécution pour tous et annulez son enregistrement dans les méthodes Ondestroy. Je n'ai jamais trouvé d'exemple de code officiel pour la mise en œuvre du récepteur d'exécution et, finalement, je l'ai mis en œuvre avec succès depuis plusieurs mois. Oui, ce n'était pas un travail intelligent, car Google
Quand utiliser le service de premier plan:
Seulement si vous souhaitez implémenter des récepteurs de diffusion ... Si vous ne souhaitez implémenter aucun récepteur de diffusion; RESTE LOIN.......
Astuce-2:
VOUS: - J'ai récemment remplacé tous mes services de services de premier plan et
JobIntentService
** le service a sa qualité de: **
Je viens juste de faire un travail minuscule ... et juste de sortir ... il faut le quitter par StopSelf()
... Encore une fois, Services can cause data-loss
s'il est appelé plusieurs fois ... Comme le même fil de service peut être exécuté plus d'une fois ... Encore une fois si vous voulez qu'un service fasse beaucoup de travail ... Utilisez START_STICKY
... Mais encore une fois, ce n'est pas recommandé et je vous l'ai déjà suggéré, quand l'utiliser dans le conseil 1.
** Intentservice a sa qualité de: **
Si vous exécutez des tâches relativement longues et que vous avez property of execution serially only
, si vous appelez encore et encore la même intentService
, tous les appels seront conservés dans une queue
et seront exécutés one by one
après avoir terminé one by one
. Ce qui n’est pas le cas dans le service décrit ci-dessus. Il se termine tout seul ... pas besoin de le terminer par un développeur .. !!
** Qualité unique de tous: **
Une fois qu’ils sont crashed
, Android peut les empêcher d’appeler à l’avenir sans vous en avertir lors du blocage de l’application. Doit être manipulé avec try-catch-exception
à avoid crash
. Encore une fois ... Si you are implementing threads within services
puis try-catch-exception
will not save your application from being crashing
...
** ALORS CE QUE CELA ET COMMENT LE METTRE EN OEUVRE ALORS: **
Utilisez FireBaseJobScedular
: -
EVEN ALL THE TIME RUNNING TASK
EVEN SUPPORTED BY NON STANDARD COMPANIES
comme vivo, mi, oppo, one + 3, ... qui prend stock-Android
le modifie et donne des noms tels que FunTouchOs, ColorOs, OxygenOsGooglePlyService
et s'exécute à l'intérieur. De toute évidence, les entreprises non standard n'empêcheraient pas les applications Google de s'acquitter de leurs tâches.Oreo
.., Même si je l’ai testé sur Android P
et fonctionne sous Android version 5.0 en tant que tâches AlarmManager
.minsdk above 16
, target sdk 26
comme si vous vouliez télécharger votre application sur google play
, il est maintenant obligatoire et cette nouvelle aurait été entendue par vous. et compile sdk 26
.JobService
dans le manifeste et utilisez une permission de ligne unique de receive_boot_complete
cold boot
et hot boot
you can focus on actual tasks
.return false
pour indiquer que la tâche est terminée et que le JobService sera terminé.Pourquoi je suggère parce que je suis CTO
d'une société bien -UNKNOwn
et que j'ai été confronté aux problèmes causés par foreground service
parmi les nombreux types de fabricants de téléphones Android ... Ce n'est pas le Apple and ios
et nous avons dû le vivre. Je reste développeur depuis 18 ans et je code surtout aujourd'hui ... dans tous les projets de développement et leurs stratégies de développement sont uniquement conçues par moi.
Corrigez-moi ... aussi ... Comme vous n'avez pas mentionné
what your tasks
etproject
est lié à ... et à ce que vous voulez exactement faire enforeground service and intent-service
... Faites-moi savoir ..., je me ferai un plaisir de vous aider. C’est une réponse théorique générale plutôt que ce que vous voulez .... Mais pour vous donner une réponse réelle, j’aurai besoin de la portée de votre projet.
JobIntentService qui agit comme si Intent Service n'était pas arrêté une fois le travail terminé
Le problème se situe dans votre méthode de classe de classe FixeJobIntentService dequeueWork.
Essayez de changer quelque chose comme ci-dessous
GenericWorkItem superValue = super.dequeueWork();
if (superValue != null) {
return new FixedGenericWorkItem(superValue);
}
return null;
En regardant le code de JobIntentSerivce, la logique du processeur des éléments de travail est présentée ci-dessous, c'est-à-dire jusqu'à ce qu'il ne reste aucun élément de travail dans la file d'attente, tous les éléments sont traités (par exemple, onHandleWork est appelé pour chaque élément).
while ((work = dequeueWork()) != null) {
if (DEBUG) Log.d(TAG, "Processing next work: " + work);
onHandleWork(work.getIntent());
if (DEBUG) Log.d(TAG, "Completing work: " + work);
work.complete();
}
Dans votre implémentation, le problème survient après le traitement du premier élément de travail. Super.dequeueWork () renvoie null, dont vous ne vous occupez pas, et envoyez simplement un nouvel objet FixedGenericWorkItem en transmettant la valeur null. Vous remarquerez peut-être qu'une valeur null est transmise à votre onHandleWork lors de vos appels suivants.
J'espère que cela vous aidera à résoudre votre problème.
Je pense que vous avez juste besoin de ce code. Créez une nouvelle classe MyJobIntentService, écrivez cette partie du code et appelez postData () pour démarrer votre service.
public class MyJobIntentService extends JobIntentService {
public static void postData(Context context, String data) {
final Intent intent = new Intent(context, MyJobIntentService.class);
intent.setAction(INITIAL_ACTION);
intent.putExtra(SAMPLE_ID, data);
enqueueWork(context, MyJobIntentService.class, 1000, intent);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
Ln.d("Cancelled service");
super.onDestroy();
}
@Override
protected void onHandleWork(@NonNull Intent intent) {
if (intent != null) {
final SampleRequest sampleRequest = requests.get(intent.getAction());
if (sampleRequest != null) {
try {
// perform some networking operations
} catch (Exception ex) {
Log.d("Error for intent ");
}
Log.i("send action ");
} else {
Log.e("action not found for ");
}
}
}
}
Et assurez-vous d'ajouter votre service dans le fichier manifeste
<service
Android:name="service.MyJobIntentService"
Android:exported="false"
Android:permission="Android.permission.BIND_JOB_SERVICE" />