51 votes

Utilisation d'Android : processus

J'ai ce fichier AndroidManifest.xml :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1" android:versionName="1.0.0.0721"
android:process="com.lily.process" package="com.lily.test">

    <provider android:authorities="com.lily.test"
      android:name="com.lily.test.provider" 
      android:process="com.lily.process">
    </provider>

"Android:process" est ajouté à la fois comme balise manifest et comme balise provider. Je sais que s'il est ajouté comme balise provider, le provider peut être exécuté dans le processus "com.lily.process". Mais quel est son usage lorsqu'il est écrit en tant que balise de manifeste ? J'ai essayé, mais tous les composants n'ont pas pu être exécutés dans le processus qu'il a identifié.

0 votes

Il semble que vous ayez un paquet supplémentaire dans le nom du fournisseur "com.com".

124voto

Carl Points 5553

Je suis d'accord pour dire que peu de gens trouveront Android:process utile en tant qu'attribut de la balise d'application. Cependant, je l'ai trouvé utile en tant qu'attribut de la balise activité étiquette.

Le but de android:process sur une activité consiste à spécifier que votre activité doit être lancée dans un processus portant un nom spécifique. Le choix de ce nom peut être utilisé soit pour isoler l'activité dans son propre processus (différent de celui qui l'a lancée), soit pour la forcer à cohabiter dans un seul processus avec d'autres activités qui utilisent le même nom.

Selon le guide de développement ( http://developer.Android.com/guide/topics/manifest/activity-element.html ) :

"Si le nom attribué à cet attribut commence par deux points (':'), un nouveau processus, privé à l'application, est créé lorsqu'il est nécessaire et l'activité s'exécute dans ce processus. Si le nom du processus commence par un caractère minuscule, l'activité s'exécutera dans un processus global de ce nom, à condition qu'elle en ait l'autorisation. Cela permet aux composants de différentes applications de partager un processus, ce qui réduit l'utilisation des ressources."

J'ai récemment trouvé cet attribut utile pour résoudre un problème que j'avais avec le lancement d'une activité d'aide pour une application qui, dans certaines circonstances, était assez proche de la limite du tas de 16 Mo qui s'applique encore à certains appareils. Dans ces situations, le lancement de l'activité d'aide faisait dépasser la limite à mon application, ce qui entraînait une fermeture forcée.

En utilisant le android:process j'ai pu spécifier que mon activité d'aide devait être lancée dans un processus distinct. Ce processus avait son propre tas de 16 Mo et n'était pas comptabilisé dans le tas de mon application principale qui le lançait. Cela a empêché de façon permanente et complète mon application de manquer d'espace de stockage et de se bloquer lors du lancement de l'aide.

Si votre application de lancement porte le nom de paquet

com.mycompany.mymainapp

et se voit donc attribuer un nom de processus correspondant à cette même chaîne, alors, si vous utilisez la fonction

android:process=":myhelp"

sur votre activité lancée, le nom de processus lui sera attribué

com.mycompany.mymainapp:myhelp

et ce processus aura son propre ID de processus distinct, que vous pouvez visualiser (par exemple dans DDMS).

C'est du moins ce que j'ai constaté. Mes tests ont été effectués jusqu'à présent sur un vieux Moto Droid fonctionnant sous CM6 (Android 2.2.1), configuré pour avoir une limite de tas de 16 Mo.

Dans mon cas, comme je ne voulais pas que l'utilisateur perçoive l'aide comme étant distincte de mon application, j'ai inclus l'option

android:excludeFromRecents="true"

pour empêcher l'activité d'aide d'apparaître dans la liste des applications récentes (appui long sur Accueil). J'ai également inclus

android:taskAffinity="com.mycompany.mymainapp.HelpActivity"

où ActivitéAide est le nom de l'activité d'aide, pour séparer l'activité dans sa propre tâche.

J'ai aussi ajouté :

android:launchMode="singleInstance"

pour éviter que de multiples instances de cette application ne soient créées chaque fois que l'utilisateur invoque l'aide.

J'ai également ajouté le drapeau :

Intent.FLAG_ACTIVITY_NEW_TASK

à l'intention utilisée pour lancer l'activité d'aide.

Ces paramètres peuvent être nécessaires ou non, en fonction de l'utilisation que vous faites de l'application android:process attribut.

Compte tenu de la fréquence à laquelle on se heurte à des limites de mémoire lorsqu'on développe pour des appareils Android, disposer d'une technique qui peut, dans certains cas, vous permettre de diviser des parties de votre application en processus distincts, chacun avec son propre tas, semble être un cadeau merveilleux. Il peut y avoir des dangers cachés dans cette façon de faire que je n'ai pas encore considérés ou expérimentés, mais jusqu'ici, tout va bien, dans mon cas particulier.

0 votes

Merci pour votre réponse, c'était très utile ! Je me demande si vous pourriez m'éclairer sur la façon dont les processus distants sont tués lorsqu'un utilisateur fait glisser l'application dans l'interface utilisateur "applications récentes". Je lis cette question et je suis curieux de voir si vous avez eu le même comportement.

0 votes

@Steven : C'est très intéressant, je n'avais pas du tout connaissance de ce comportement. La philosophie d'Android consiste généralement à laisser le système d'exploitation décider, sauf lorsque l'utilisateur utilise le bouton Précédent pour sortir complètement d'une application. Je viens d'essayer de lancer ma propre application play.google.fr/store/apps/ (qui utilise cette approche pour son aide), et le fait de faire glisser le processus de l'application principale ou le processus d'aide semble les tuer tous les deux (même si l'autre reste dans la liste des utilisations récentes). Vous pouvez essayer de le faire en exécutant DDMS pour être sûr.

0 votes

Je comprends l'effort que vous avez fait pour cacher l'activité des Récents. Mais cela ne devrait-il pas avoir un rapport avec le gonflement d'un nouveau processus ?

7voto

see2851 Points 102

@Carl

Il peut y avoir des dangers cachés :

  • La mémoire ne peut pas être libérée lorsqu'il y a un service d'arrière-plan (par exemple : Android:process=":myhelp") dans le même processus.
  • Le modèle Singleton ne peut pas être utilisé.

Ref : http://developer.Android.com/training/articles/memory.html#MultipleProcesses

La taille du processus a maintenant presque triplé, passant à 4MB, simplement en montrant du texte dans l'interface utilisateur. Cela conduit à une conclusion importante : Si vous devez Si vous devez diviser votre application en plusieurs processus, un seul processus devrait être responsable de l'interface utilisateur. Les autres processus doivent éviter toute IU, car car cela augmentera rapidement la RAM requise par le processus (en particulier (surtout lorsque vous commencez à charger les ressources bitmap et autres ressources). Il peut alors difficile, voire impossible, de réduire l'utilisation de la mémoire une fois l'interface utilisateur dessinée.

0 votes

Dans mon cas, l'utilisateur accède à l'aide à partir de l'activité principale de l'application, et quitte généralement le processus d'aide une fois l'aide consultée, pour revenir à l'activité principale et à son processus. Donc, pour un peu de mémoire supplémentaire temporaire pendant l'affichage de l'aide, cela fonctionne très bien. Et bien sûr, mon processus d'aide implique une interface utilisateur, mais cela ne pose pas de problème. Je pense que si l'utilisateur devait passer directement de l'affichage de l'aide à une autre application, le système d'exploitation serait capable de faire sortir de la mémoire les deux processus de ma propre application afin de fournir de la mémoire, si cette autre application en a besoin.

0 votes

Je voudrais noter que le processus d'aide dans mon propre exemple n'est pas un service ; c'est une activité. De plus, le processus d'aide n'utilise pas d'objets créés dans le processus principal, donc rien n'empêche l'utilisation d'un pattern singleton dans mon processus principal, et en fait j'utilise ce pattern.

4voto

Android : processus doit être utilisé avec attention

(Citation du lien ci-dessous)

Un comportement peu connu et apparemment non documenté d'Android est que chaque processus d'une application possède sa propre instance d'application.

Ainsi, si vous avez un service qui s'exécute dans un processus différent, l'appel à startService() initiera la classe Appplication pour votre application.

En savoir plus Démarrage du service dans les appels Android Applications onCreate

2voto

Android:process et shareduserid peuvent être utilisés pour transmettre des ressources entre les paquets. Dans mon cas, cela devient pratique maintenant :)

Exemple de code source : https://github.com/ikust/hello-sharedprocess

0 votes

Le lien est mort.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X