Communication entre activité et service. Basculer entre les écrans d'application Transmission de données entre Activati
D'une manière ou d'une autre, j'ai eu une tâche de transférer des données du service à Activat. La recherche de solutions dans le SDK standard a commencé, mais comme il n'y avait pas de temps, alors a volé une mauvaise solution en tant que base de données. Mais la question a été ouverte et après un certain temps, j'ai compris avec une manière plus correcte, qui est en SDK - en utilisant les classes de message, gestionnaire, messager.
Idée
Nous devons transmettre des données d'Activat au service et à votre retour. Comment faisons-nous ça? Pour résoudre notre tâche, nous avons déjà tout ce dont vous avez besoin. Tout ce dont vous avez besoin est de lier le service à l'atitivité à l'aide de BINDService, transférez les paramètres souhaités et un peu de magie sous la forme de classes de messages. Et la magie consiste à utiliser les variables d'instance de message et en particulier ReplyTo. Cette variable est nécessaire pour nous afin que nous puissions faire référence à l'instance de service Messanger d'Activati \u200b\u200bet au service à la copie de Messanger-une copie. En fait, pas si simple. Au moins pour mon esprit le plus doué. En partie, j'améliore simplement la documentation qui est déjà - les services également, il existe un bon exemple sur Stackoverflow. En tout état de cause, j'espère que l'article sera utile au moins quelqu'un et je n'ai pas osé pas en vain.
Exemple
Par exemple, nous mettons en œuvre un service qui augmentera et réduira la valeur du compteur et renvoie le résultat dans Activati \u200b\u200bdans TextView. Le code de mise en page est omis, car il y a deux boutons et un champ de texte - tout est simple.
Ventes
Je vais donner un code entièrement activat:
MainAlactivité de la classe publique Étend Activité (Static String Tag \u003d "TestService"; Testserviceconnection TestServconn; TextView Testtxt; Messenger Final Messenger \u003d New Messenger (Nouveau Messenger (nouveau Incominghandler ()); Messenger ToserviceMessenger; @Override Public Void OnCreate (Bundle SavedInstancestate) (Super. Oncreate (SavedInstanCestate); SetContentView; Testtxxt \u003d (TextTextTxt \u003d (TextVietTexte) (r.id.test_txt); BindService (nouvel intention), (testServconn \u003d nouveau testserviceconnection ()), contexte .bind_auto_create);) @Override publique annulation oitroy () ( Super.ondeSestroy (); Unbindservice (TestServconn);) Public Noid Countincrcliquez (Bouton d'affichage) (NULL, TESTSERVICE.COUNT_PLUS); MSG.ReplyTo \u003d Messenger; essayez (ToserviceMessenger.Send (MSG);) Catch (E.PrintStackTrace () ;)) Public Void CountDecllick (Bouton Afficher) (NULL, TESTSERVICE.COUNT_MINUS); MSG .Replyto. \u003d messager; Essayez (Toservicemessenger.send (msg);) Catch (E.PrintStackTrace ();));)) La classe privée Incominghandlerler étend le gestionnaire (@override publique vide handlemessage (msg.Que) (TestService de cas. get_count: log.d (étiquette) ( Activité) ... Obtenir le compte "); Testtxt.setText (" "+ msg.arg1); pause;))))) Testserviceconnection de classe privée Confient ServiceConnection (@Override Public Void Onserviceconnected (Nom de la composeName, Ibinder Service) (ToserviceMessenger \u003d New Messenger) ; // Envoie la valeur initiale du message MSG \u003d Message.Obtain Compteur (NULL, testService.set_count); msg.replyto \u003d Messenger; msg.arg1 \u003d 0; // Notre compteur Essayez (ToserviceMessenger.Send (MSG);) Catch (RemoteeException E) (E.PrintStackTrace ();) @override Public Void OnserviceSischeconnected (Nom de la nomenneName)))
Je vais expliquer. Lors de la création d'Activat, nous sommes immédiatement liés au service, en implémentant l'interface ServiceConnection et envoyez un message au service "Définir la valeur de compteur", en passant à zéro et à la création d'un ToserviceMessanger, en passant l'interface Ibinder sur le concepteur. Au fait, dans le service, il est nécessaire de renvoyer ce eHemple, sinon il y aura NPE. Avec cette classe, nous envoyons le message au service. Et voici la magie - nous enregistrons notre autre instance de messagerie à la variable ReplyTo - celui qui reçoit une réponse du serveur et c'est à travers celui-ci qui communiquera avec Activat.
Pour recevoir un message du service, utilisez votre gestionnaire et recherchez simplement des variables dont nous avons besoin et de faire une action sur eux. Par clics sur les boutons (CountinCrcrCllick, CountDecllick Méthodes), envoyez des demandes au service, spécifiant l'action souhaitée dans la variable msg.Que.
Package com.example.serviceTest; Import android.app.service; Import android.content. *; Importer Android.os. *; Importer Android.os.Processes; Importer Android.Util.log; Public Class TestService prolonge le service (finale statique du public INT Nombre_PLUS \u003d 1; finale statique publique INT Nombre_minus \u003d 2; Public statique finale int Set_Count \u003d 0; Public statique finale int get_count \u003d 3; int compte \u003d 0; Incominghandler inhhandler; Messenger Messanger; Messenger toactivitéMessenger; @Override public vide surcreee () (Super.oncreate (); Thread Handlerthread \u003d nouveau manutention ("ServiceSarTarguments", processus.thready_priority_background); thread.start (); Incominghandler (thread.getlooper ()); Messanger \u003d Nouveau messager (inhhandler);) @override publique Ibinder ONBIND (Retour Messanger.getBinder ();) @Override Intention publique OnstartCommand (Retour Start_Sticky;) // Activités du gestionnaire de messages Incominghandlert Extend Handler (Super Looper) (Looper) (Looper Looper) @override Public Void Handlemessage (Message MSG) (//super.handlemessage(MSG); toactivitymess Enger \u003d msg.replyto; Commutateur (msg.what \u003d msg.arg1; log.d (MainActivity.tag, "(Service) ... Ensemble de comptage"); casse-caisse Nombre_plus: Comptez ++; log.d (mainActivity.dag, " ) ... comte plus "); casse-caisse comptage_minus: log.d (MainAlyCity.tag," (service) ... comptage moins "); Compter--; Break;) // Envoyer une valeur de compteur dans le message d'activation OUTMSG \u003d Message.Obtain (InAver, Get_Count); outmsg.arg1 \u003d compte; outmsg.replyto \u003d Messanger; Essayez (si (toactivitéMessenger! \u003d Null) toactivityMessenger.send (OutMSG);) Catch (E.PrintStackTrace ();)))))))))))))))))))))))))))))))
Tout par analogie avec logique dans Activiti. Je ne sais même pas si vous avez besoin d'expliquer quelque chose. Le seul moment est que j'envoie immédiatement une demande à Activat dans ManuLemessage, en utilisant la variable magique ReplyTo et tirant le messager ci-dessus ci-dessus. Et le deuxième moment que j'ai déjà dit est:
@Override publique Ibinder ONBIND (Intention Arg0) (retour Messanger.getBinder (););)
sans quel tout tombe. C'est cette instance d'interface qui sera transmise à ServiceConnection.
Conclusion
En général, tout. Exemple d'interaction aussi artificiel d'activation et de service. Il me semble que l'interaction non triviale est jolie, bien que quelqu'un puisse sembler autrement.
Questions, clarifications et autres dans les PM. Il peut y avoir des inexactitudes sur tous les aspects, alors n'hésitez pas à écrire et à redresser.
J'espère que le poste était utile aux lecteurs.
Dernière mise à jour: 04/03/2018
Pour transférer des données entre deux activités, un objet d'intention est utilisé. Grâce à sa méthode Putextra (), vous pouvez ajouter la clé et la valeur associée.
Par exemple, transmettant de l'activité actuelle dans les chaînes "Bonjour World" de secondagity avec la clé "Bonjour":
// la création d'un objet d'intention de lancer de la secondactivity intens intense \u003d nouvelle intention (ceci, secondactivity.class); // transfert d'un objet avec la clé "Hello" et la valeur "Hello World" de l'intention.putextra ("Bonjour", "Bonjour World"); // démarrage de la démarrage de secondactivité (intention);
La méthode Putextra () est utilisée pour transmettre des données, ce qui, comme une valeur vous permet de transférer les types de données de type simples de type, int, flotteur, double, long, court, octet, char, les tableaux de ces types, ou Objet d'interface sérialisable.
Pour obtenir les données envoyées lors du chargement de secondactivity, vous pouvez utiliser oBTENIR.(), dans lequel l'objet est transmis:
Bundle arguments \u003d getintent (). GetExtras (); Nom de cordes \u003d arguments.get ("Bonjour"). Tostring (); // Bonjour le monde.
Selon le type de données envoyé, lors de la réception, nous pouvons utiliser un certain nombre de méthodes d'objet de paquet. Tous acceptent la clé d'objet comme paramètre. Les principaux sont:
obtenir (): méthode universellequi renvoie la valeur du type d'objet. En conséquence, le champ de réception doit être converti au type souhaité.
getString (): retourne la chaîne de type d'objet
getint (): retourne la valeur de type int
getByte (): Retourne la valeur du type d'octet
getchar (): retourne la valeur de type char
gethort (): retourne une valeur de type courte
getLong (): retourne une valeur longue
getFlove (): Retourne la valeur de Type Float
getdouble (): retourne une double valeur
gETBOOLEAN (): Retourne une valeur de type booléen
getchararray (): renvoie une gamme d'objets de caractère
getintarray (): retourne un tableau d'objets int
getfloatarray (): retourne un tableau d'objets de flotteur
obtiendable (): Retourne l'objet d'interface Serializable
Permettez-nous dans le projet deux activités suivantes: MainAlactivité et secondactivité.
Dans le code de secondactivité, nous déterminerons les données obtenant:
Package com.example.eugene.serializeApp; Importer Android.Support.v7.app.app.appCompatiactivité; Importer android.os.bundle; Importer android.widget.textview; La classe d'enseignement de la classe publique étend l'appelcompativactivité (@override protégé Void Oncreate (Bundle SavedInstateTate) (Super.Oncreate (SavedInstancestate); TextView TextView \u003d Nouveau TextView (this); TextView.setextsize (20); TextView.Settypadding (16, 16, 16, 16 ); Bundle arguments \u003d getintent (). GetExtras (); si (arguments! \u003d Null) (String Name \u003d Argments.get). ToString (); String Company \u003d Arguments.Getstring ("Société"); Int Prix \u003d Arguments. getint ("prix"); textview.setText ("Nom:" + nom + "\\ NCompany:" + société + "\\ Nprice:" + prix);) setContentView (textview););
Dans ce cas, dans la deuxièmeactivité, nous obtenons toutes les données de l'objet Bundle et les affichent dans la zone de texte TextView. On suppose que cette activité sera transmise trois éléments - deux lignes avec noms et clés de la société et une clé avec un prix clé.
Nous définirons maintenant le transfert à la deuxièmeactivité des données. Par exemple, nous définissons l'interface suivante pour la MainActivity dans le fichier Activity_Main.xml:
Voici trois champs de texte pour la saisie de données et un bouton.
Dans la classe MainAlactivité, nous définissons le contenu suivant:
Package com.example.eugene.serializeApp; Importer android.content.Inter; Importer Android.Support.v7.app.app.appCompatiactivité; Importer android.os.bundle; Importer Android.View.View ;View; Import android.widget.editextText; La main-d'œuvre de la classe publique prolonge l'appcCompativittivité (Vidon protégé @override Oncreate (Bundle SavedInstatetate) (Super.Oncreate (SavedInstancestate); SetContentView (R.Layout.Activity_main);) Vidéoclick Public OnClick (View V) (Final EditText Nametext \u003d FindvevyId (R.ID .name); final EditText CompanyText \u003d FindVietById (r.id.company); final EditText PritText \u003d FindVietByID (R.ID.Price); Nom de la chaîne \u003d Nametext.gettext (). Tostring (); String Company \u003d CompanyText.getText ( ) .Tostring (); int Price \u003d INTEGER.PARSINTINT (PRISTEXTEXTEXT (). TOSTRING ()); INTENS INTENS \u003d NOUVELLE INTENTIF (CLASSECTIVITÉ.CLASSTRAGE ("NOM", NOM); Intention. Putextra ("Société", société); Intention.putextra ("prix", prix); startactivité (intention);)))
Dans le bouton Appuyez sur la touche, vous obtenez les données saisies dans les champs de texte, les données et les transmettent à l'objet d'intention à l'aide de la méthode Putextra (). Puis lancez la deuxièmeactactivité.
En conséquence, lorsque vous cliquez sur le bouton, le secondactivity, ce qui recevra certaines données saisies dans des champs de texte.
Transfert d'objets complexes
Dans l'exemple, des données simples ont été transmises - des numéros, des lignes. Mais nous pouvons également transmettre des données plus difficiles. Dans ce cas, le mécanisme de sérialisation est utilisé.
Par exemple, le projet sera défini par la classe de produits:
Package com.example.eugene.serializeApp; Importer java.io.Sérialisable; Produit de classe publique implémente sérialisable (nom de cordes privées; société de cordes privée; prix privé int; produit public (nom de cordes, société de cordes, int Price) (this.price \u003d nom; ceci.price \u003d Prix;) Public String getname () (nom de retour;) Public Void SetName SetName (Nom de la chaîne) (ce nom \u003d Nom;) String publique GetCompany () (Société de retour;) Public Void SetCompany (String Company) Int getprice () (prix de retour;) Public Void Setprice (Int Prix) (Ceci.Price \u003d;))
Il convient de noter que cette classe implémente l'interface sérialisable. Maintenant, vous allez changer le code de MainAlactivité:
Package com.example.eugene.serializeApp; Importer android.content.Inter; Importer Android.Support.v7.app.app.appCompatiactivité; Importer android.os.bundle; Importer Android.View.View ;View; Import android.widget.editextText; La main-d'œuvre de la classe publique prolonge l'appcCompativittivité (Vidon protégé @override Oncreate (Bundle SavedInstatetate) (Super.Oncreate (SavedInstancestate); SetContentView (R.Layout.Activity_main);) Vidéoclick Public OnClick (View V) (Final EditText Nametext \u003d FindvevyId (R.ID .name); final EditText CompanyText \u003d FindVietById (r.id.company); final EditText PritText \u003d FindVietByID (R.ID.Price); Nom de la chaîne \u003d Nametext.gettext (). Tostring (); String Company \u003d CompanyText.getText ( Supporarytext.getText () .Tostring (); int Price \u003d INTEGER.PARSINTINT (PRISTEXT.GETTEXT (). TOSTRING ()); produit de produit \u003d nouveau produit (nom, entreprise, prix); Intention Intention \u003d Nouvelle intention (ceci, secondactivité .Class); intent.padextra (produit.class.getsimplename (), produit); startactivité (intention);))
Maintenant, au lieu de trois données dispersées, un objet produit est transmis. En tant que clé, le résultat est le résultat de la méthode produit.class.getsimplename (), qui renvoie essentiellement le nom de la classe.
Et changer la classe de secondactivity:
Package com.example.eugene.serializeApp; Importer Android.Support.v7.app.app.appCompatiactivité; Importer android.os.bundle; Importer android.widget.textview; La classe d'enseignement de la classe publique étend l'appelcompativactivité (@override protégé Void Oncreate (Bundle SavedInstateTate) (Super.Oncreate (SavedInstancestate); TextView TextView \u003d Nouveau TextView (this); TextView.setextsize (20); TextView.Settypadding (16, 16, 16, 16 ); Bundle arguments \u003d getintent (). GetExtras (); produit de produit final; si (arguments! \u003d Null) (produit \u003d (produit) arguments.GetsRetsImplename ()); textview.setText ("Nom: "+ Produit.getname () +" \\ ncompany: "+ produit.getcompany () +" \\ NPRICE: "+ string.valueof (produit.getprice ()));) SetContentView (TextView);));
La méthode getorialisable () est appliquée pour obtenir des données, car la classe de produit implémente l'interface sérialisable. Ainsi, nous pouvons transmettre un seul objet au lieu d'une numérotation de données disparates.
Salut.
Vous devez transmettre les données obtenues via UART dans l'activité. Cela peut être fait en créant un flux d'activité dans lequel organiser tandis que le cycle (! IsInterrupted ()) et soumettez des données du tampon UART. Après cela, en appelant le courant d'activité de l'interface utilisateur - MainAlactivité.Cela.RunonUthread (nouveau runnable (), effectuez les actions nécessaires avec cette activité. Mais si nous appelons toute autre activité à partir de l'activité principale, le thread organisé ne permet pas de transmettre Données à l'activité nouvellement créée. Si je comprends correctement, de sorte que les données du flux peuvent être transférées à n'importe quelle activité, le flux doit être créé non en activité, mais en service.
Question: UAR a reçu des données, dans le flux (qui est créée dans le service), il est nécessaire de transférer des données à l'activité, qui est maintenant active, comment cela peut-il être fait et qui est-ce fait du tout?
1 réponse
Dans chaque activité, créez un gestionnaire. Dans la méthode ONRESUME (), cette activité rend BINDService (). Là, l'un des paramètres est l'interface ServiceConnection. La mise en œuvre est au moins la même activité. Mettre en œuvre sur Serviceconnected (). Dans ce rappel, l'un des paramètres concerne le service lui-même. Alors appelez le Sethadlerler () de ce service. Passez le gestionnaire là-bas, qui est dans l'activité actuelle. Et voici les données entrantes sur le lancement de UART en service sur ce gestionnaire. Au fait, le gestionnaire fonctionne traditionnellement dans le fil principal, de sorte qu'il ne sera donc pas nécessaire d'effectuer des runonuthread.
L'application ne consiste pas toujours en un seul écran. Par exemple, nous avons créé très programme utile Et je veux connaître l'utilisateur qui est son auteur. Il appuie sur le bouton "À propos du programme" et tombe sur nouvel écranoù des informations utiles sur la version du programme, l'auteur, l'adresse du site, combien de chats de l'auteur, etc. Percevoir l'écran d'activité en tant que page Web avec un lien vers une autre page. Si vous regardez le code dans le fichier MainActivity.java. Des leçons antérieures, vous verrez que notre classe Activité principale. fait également référence à Activité (ou ses héritiers) ou, étant donné plus précisément, hérité de lui.
La maîtrise de la classe publique étend l'appelccompaticotivité
Comme il est facile de deviner, nous devrions créer une nouvelle classe, ce qui peut être similaire à Activité principale. Puis en quelque sorte, passez-le lorsque vous appuyez sur le bouton.
Pour l'expérience, nous allons prendre le programme de la première leçon et utiliserons le bouton pour expériences (ou créerons un nouveau projet avec un bouton à l'écran). Ensuite, créez un nouveau formulaire à afficher. informations utiles. Par exemple, montrez à l'utilisateur qui fait un chat quand cela reste à gauche et à droite. D'accord c'est très une information importantdonner la clé de l'univers descriffes.
Créer une nouvelle activité sera manuellement, bien que dans le studio il y ait modèles prêts. Mais il n'y a rien de compliqué et pour une meilleure compréhension, il est utile de tout faire avec vos mains.
Créer un nouveau fichier de marquage XML activité_about.xml. dans le dossier res / mise en page.. Cliquez avec le bouton droit sur le dossier disposition. et sélectionnez dans le menu contextuel Nouveau | Fichier de ressources de mise en page.. Une boîte de dialogue apparaît. Dans le premier champ, entrez le nom du fichier activité_about. Dans la seconde, vous devez entrer dans l'élément racine. Par défaut, il se trouve Contraintlayout.. Nous lavons le texte et entrons ScrollView.. Entrée Plusieurs caractères suffisent pour que le studio suggère des options prêtes à l'emploi, vous pouvez appuyer immédiatement sur Entrée, sans attendre le mot Intrée complète:
Il éteint le billet correspondant dans lequel l'élément insérera Affichage..
Les informations seront supprimées des ressources, nommément à partir d'une ressource à chaîne. about_text.. Maintenant, il est mis en évidence en rouge, signalant sur l'absence d'informations. Il a été possible de cliquer Alt + Entrée. Et entrez du texte dans la boîte de dialogue. Mais pour notre exemple, cette méthode ne conviendra pas, car notre texte sera multiplay, en utilisant des caractères de contrôle. Par conséquent, procédez d'une manière différente. Fichier ouvert res / valeurs / strings.xml Et entrez le texte suivant manuellement:
Nous avons utilisé les balises de formatage de texte de type HTML les plus simples , , . Pour notre exemple, il suffit de mettre en évidence les mots gras qui appartiennent au chat et à la direction du mouvement. Transférer du texte à nouvelle chaîne Utiliser des symboles \\ N.. Ajoutez une autre ressource de chaîne pour l'en-tête du nouvel écran:
Marquage compris. Ensuite, vous devez créer une classe pour la fenêtre Aboutactivité.java.. Sélectionnez dans le menu Fichier | Nouveau | Classe Java. et remplissez les bons champs. Au début, il suffit de spécifier uniquement le nom. Puis désastre avec d'autres champs.
Nous obtenons la pièce.
Maintenant, la classe est presque vide. Ajoutez le code manuellement. La classe doit être héritée de la classe abstraite Activité ou ses proches comme Fragmentactivité., AppCompatactivité etc. Finir Étend l'activité.. La classe d'activité doit avoir une méthode oncreate (). Nous mettons le curseur de la souris dans la classe et choisissons dans le menu. Code | Remplacer les méthodes. (CTRL + O). Dans la boîte de dialogue, nous recherchons la classe souhaitée, vous pouvez composer les premiers caractères pour rechercher rapidement sur le clavier. Dans la méthode créée, vous devez appeler la méthode setContentView ()qui chargera le balisage préparé à l'écran. Nous aurons cette option.
Forfait ru.alexanderklimov.hellellyld; Import android.app.activité; Importer android.os.bundle; / ** * Créé par Alexander Klimov le 01.12.2014. * / La classe publique AboutActivité étend une activité (SavedInstancestate); setContentView (r.layout.activity_about);));))
Maintenant, la chose la plus importante commence. Notre tâche consiste à accéder à un nouvel écran lorsque vous cliquez sur le bouton sur le premier écran. Revenir en classe Activité principale.. Nous écrivons un gestionnaire de clic click:
Public Void OnClick (Maintentivité.Cette, AboutActivity.class); startactivité (intention);)
Ici, j'ai utilisé un moyen de gérer le bouton en appuyant sur ce qui a été dit dans la classe.
Pour démarrer un nouvel écran, vous devez créer une instance de classe. Intention et spécifiez la classe actuelle dans le premier paramètre et dans la seconde - la classe pour la transition, nous l'avons Aptitude. Après cela, la méthode est appelée startactivité ()qui lance un nouvel écran.
Si vous essayez maintenant de vérifier le fonctionnement de l'application dans l'émulateur, vous recevrez un message d'erreur. Qu'avons-nous fait de mal? Nous avons manqué une étape importante. Besoin d'enregistrer nouveau Activité Au manifeste Androidmanifest.xml.. Trouvez ce fichier dans votre projet et cliquez dessus deux fois. Une fenêtre d'édition de fichiers s'ouvre. Ajouter nouvelle étiquette
La ressource à cordes était donc utile. about_title.. Exécutez l'application, cliquez sur le bouton et obtenez une fenêtre. Sur le programme. Nous avons donc appris à créer une nouvelle fenêtre et à l'appeler pour cliquer sur le bouton. Et à notre disposition, un programme mégaudobal est apparu - il y aura toujours un soupçon à la main, ce qui rend un chat quand cela reste à gauche.
Je regarde à nouveau que la deuxième classe d'activité créée devrait être héritée de la classe Activité ou lui comme ( Listactivité. etc.), avez un fichier de balisage XML (si nécessaire) et être enregistré dans le manifeste.
Après avoir appelé la méthode startactivité () Une nouvelle activité sera lancée (dans ce cas Aptitude), il sera visible et se déplace vers le haut de la pile contenant les composants de travail. Lorsque vous appelez une méthode tERMINER () De la nouvelle activité (ou lorsque vous appuyez sur la touche Matériel de retour), il sera fermé et supprimé de la pile. Le développeur peut également passer à la précédente (ou à une autre) activité en utilisant la même méthode startactivité ().
Créez un troisième écran - un moyen de paresseux
Les programmeurs, comme les chats, sont des créatures paresseuses. Rappelez-vous constamment que pour une activité, vous devez créer une balise et une classe héritée de Activité, puis n'oubliez pas d'enregistrer la classe dans le manifeste - Oui, NAFIG.
Dans ce cas, sélectionnez dans le menu Fichier | Nouveau | Activité | Activité de base (ou autre modèle). En outre, une fenêtre familière pour la création d'une nouvelle activité apparaîtra. Remplissez les champs nécessaires.
Cliquez sur le bouton TERMINER Et l'activité sera prête. Pour vous assurer que, ouvrez le fichier manifeste et vérifiez la disponibilité. nouvel enregistrement. Je ne dis plus sur les fichiers de la classe et du balisage, ils apparaîtront devant vous.
Seul ajoutez un nouveau bouton sur l'écran d'activité principale et écrivez le code pour la transition vers l'activité créée.
Au début, je vous conseillerais de créer manuellement tous les composants nécessaires à la nouvelle activité de comprendre la relation entre la classe, le balisage et le manifeste. Et lorsque vous avez une main, vous pouvez utiliser l'assistant d'activité pour accélérer le travail.
Transmission de données entre activités
Nous avons utilisé l'exemple le plus simple pour appeler un autre écran d'activité. Parfois, il est nécessaire non seulement d'appeler un nouvel écran, mais également de transférer des données. Par exemple, le nom d'utilisateur. Dans ce cas, vous devez utiliser une zone spéciale extradata.qui est disponible en classe Intention.
Région extradata. - Ceci est une liste de couples valeur cléqui est transmis avec l'intention. Les lignes sont utilisées comme des clés et des valeurs que vous pouvez utiliser tous les types primitifs de données, des matrices primitives, des objets de classe Empaqueter et etc.
Pour le transfert de données à une autre méthode d'activité est utilisé putextra ():
Intention.putextra ("clé", "valeur");
La prise d'activité devrait causer une méthode appropriée: getintextra (), getStringextra () etc.:
Int compte \u003d getintent (). Getintextra ("nom", 0);
Nous remonsons l'exemple précédent. Nous avons déjà trois activités. Lors de la première activité, deux champs de texte seront placés et un bouton. Apparence Peut être comme suit:
Dans la deuxième activité Secondactivité. Élément d'installation Affichage.où nous afficherons le texte obtenu à partir de la première activité. Nous écrivons le code suivant pour la méthode oncreate () En deuxième activité.
@Override protégé Void Oncreate (Bundle SavedInstancestate) (Super.Oncreate (SavedInstanCetate); SetContentView (r.layout.activity_seconde); String UserView (r.layout.activity_second); String User \u003d "Zhyvotnyh"; String Cadeau \u003d "TextViet"; TextVietViewe (r .Id.TextViewInfo); infotextview.setText (utilisateur + ", vous avez été envoyé" + cadeau);)
Si vous démarrez le programme maintenant et appelez simplement la deuxième fenêtre, comme décrit dans la première partie de l'article, nous verrons l'inscription par défaut Jauni, tu as passé un trou du bagel. D'accord, il est assez offensant de recevoir de tels messages.
Je répare la situation. Ajouter du code de la première activité:
Public Void OnClick (View View) (editext useredittext \u003d (edittext) Findvied (r.idtttttTextuser); editext Cadedittext \u003d (editextextextexgift); Intention Intention \u003d Nouvelle intention (MainActivity.Cette, secondactivité. Classe); // Dans la touche Nom d'utilisateur, vous aurez PIHEM Texte du premier champ de texte Inent.putextra ("Nom d'utilisateur", userdittext.getText (). Tostring ()); // B Cadeau de clé Piham Texte du deuxième champ de texte Inent.putextra ("cadeau", cadeauDittext.getText (). Tostring ()); startactivité (intention);)
Nous avons placé dans un conteneur d'objet spécial Intention Deux clés avec des valeurs extraites des champs de texte. Lorsque l'utilisateur entre dans les données dans des champs de texte, ils tomberont dans ce conteneur et seront transférés à la deuxième activité.
La deuxième activité doit être prête pour une réception chaleureuse des messages comme suit (graisse surlignée).
// Valeurs par défaut String User \u003d "JAUNE"; Cadeau de chaîne \u003d "trou de la bulle"; Utilisateur \u003d getintent (). GetExtras (). GetString ("Nom d'utilisateur"); Cadeau \u003d getintent (). GetExtras (). GetString ("cadeau"); Textview infotextview \u003d (TextView) FOYVISHYID (r.id.textviewinfo); infotextview.setText (utilisateur + ", vous avez été envoyé" + cadeau);
Maintenant, le message ne ressemble pas à cela, mais même agréable pour quelqu'un. Dans des exemples difficiles, il est souhaitable d'ajouter un chèque lors du traitement des données. Il existe des situations lorsque vous exécutez une deuxième activité avec un type de données vide nULCe qui peut conduire à l'effondrement de l'application.
Dans notre cas, nous savons que nous attendons une valeur de chaîne, le code peut donc être réécrit:
Intention intention \u003d getintent (); utilisateur \u003d intention.getstringextra ("nom d'utilisateur");
Utilisateur \u003d getintent (). GetStringextra ("nom d'utilisateur");
Le programme a un désavantage - il n'est pas clair à qui nous obtenons. Toute menthe bien amenée ne prendra pas un cadeau d'une source anonyme. Par conséquent, en tant que devoirs, ajoutez une autre zone de texte pour entrer le nom de l'utilisateur qui envoie le message.
Google recommande d'utiliser le format suivant pour les touches: nom de votre package en tant que préfixe, puis la clé elle-même. Dans ce cas, vous pouvez être confiant dans l'unicité de la clé lors de l'interaction avec d'autres applications. Environ comme ceci:
Utilisateur de chaîne statique finale publique \u003d "ru.alexanderklimov.myapp.user";
Qui a mis le chat Vaska - récupérez le résultat
Cela n'arrive pas toujours à transmettre ces autres activités. Parfois, vous devez récupérer des informations d'une autre activité lorsqu'elle est fermée. Si nous utilisions la méthode startratorytivité (intention intention)Ensuite, il y a une méthode relative startatryTatorytiforresult (Intention Intention, Int DemandeCode). La différence entre les méthodes est paramètre supplémentaire Code requis.. En fait, c'est juste un entier que vous pouvez penser à vous-même. Il est nécessaire pour distinguer de qui le résultat est venu. Supposons que vous ayez cinq Écrans supplémentaires Et vous leur attribuez des valeurs de 1 à 5, et sur ce code, vous pouvez déterminer le résultat dont vous avez besoin pour traiter. Vous pouvez utiliser -1, alors ce sera équivalent à l'appel de la méthode startactivité (). Je n'obtinerai aucun résultat.
Si vous utilisez la méthode statatrytatorytiforresult ()Vous devez remplacer la méthode dans le code pour recevoir le résultat. onActivityResult () et traiter le résultat. Embrouillé? Nous nous demandons l'exemple.
Supposons que vous soyez un cerf. Des informations ont été reçues que deux morceaux de saucisses et d'autres produits ont été volés du restaurant de la table d'une personne influente. Suspusage Palo sur trois suspects - Crow, putain de chatte et chat Vaska.
Un des visiteurs a fourni une série de photos de son iPhone de poudre:
Il y a aussi une indication d'un autre témoin: Et Vaska écoute, oui mange.
Créer un nouveau projet Sherlock Avec deux activités. Sur le premier écran, il y aura un bouton pour passer au second écran et l'étiquette de texte dans laquelle le nom du voleur sera affiché.
Sur le deuxième écran, il y aura un groupe de commutateurs:
Comme nous nous attendons à une réponse du deuxième écran, nous devons utiliser la méthode. statatrytatorytiforresult () Sur le premier écran dans lequel nous allons donner une variable Choisir_thief. comme un paramètre Code requis..
Statique finale privée dans choisi_thief \u003d 0; Public Void Onclick (View V) (MainAlactivité.Cette, chooseActivity.class); startActivityForresult (questionnant, choisi_thief);)
Regardez le code. Lorsque vous cliquez sur le bouton, nous allons travailler avec le deuxième écran Choosactivité. Et lancez le deuxième écran avec l'attente du résultat.
Allez sur le deuxième écran et écrivez le code pour la deuxième activité.
Voleur de chaîne statique finale publique \u003d "ru.alexanderklimov.sherlock.thief"; Public Void Onradioclick (View V) (Intention de réponse \u003d nouvelle intention (); interrupteur (v.getid ()) (cas r.id.radiodog: répondantintent.putextra (voleur, «Putain de chatte»); casse-caisse r.id .Radiocrow: réponseInterint.putextra (voleur, "corbeau"); casse-tête r.id.radiocat: réponseInterint.putextra (voleur, "PRZHEVALSKY'S HORSE"); pause; défaut: pause (weight_ok, utilité); terminer ();)
Ici tout est simple lorsque le détective choisit le nom du criminel, puis à travers la méthode putextra () Nous passons le nom de la clé et sa valeur.
Pour plus de commodité, après avoir sélectionné, nous fermons immédiatement la deuxième fenêtre et transmettez la valeur avant la fermeture. Résultat_ok.de sorte qu'il était clair que le choix est fait. Si l'utilisateur ferme l'écran via le bouton arrière, la valeur sera transmise. Résultat_cancelé..
Méthode setsult () Prend deux paramètres: le code résultant et le résultat lui-même présenté sous forme d'intention. Le code résultant suggère ce que le résultat a pris fin au travail d'activité, en règle générale, soit Activité.Result_OK.Soit Activité.Result_canceled.. Dans certains cas, vous devez utiliser votre propre code de remboursement pour traiter des options spécifiques pour vos options d'application. Méthode setsult () Prend en charge toute valeur entière.
Si vous transmettez clairement les données via le bouton, il serait agréable d'ajouter une méthode tERMINER ()Fermer la deuxième activité comme inutile. Si la transition se produit via le bouton arrière, il n'est pas nécessaire de le faire.
Si l'utilisateur a été fermé par l'utilisateur lorsque le bouton de retour du matériel est enfoncé ou si la méthode est tERMINER () a été causé plus tôt que la méthode setsult ()Le code résultant sera installé dans Résultat_cancelé.et l'intention de retour montrera la valeur nUL.
Retourner au premier écran. Le premier écran attend une réponse du deuxième écran, vous devez donc ajouter à la méthode du code. onActivityResult ().
@Override protégé Void OnactivityResult (int DemandeCode, int CodeCode, Intention Données) (Super.onActivityResult (DemandeCode, résultatcode, données); TextView InfoTetView \u003d (TextView) Findvied (r.id.textviewinfo); si (DemandeCode \u003d\u003d Choisir_thief) ( if (résultat \u003d\u003d résultat_ok) (chaîne vol voleur \u003d data.getstringextra (chooseactivity.thief); infotextview.settext (voleur););););); // Nous effacons le texte)))))
La méthode attend les données entrantes avec le code. Choisir_thief.et si ces données arrivent, récupérez la valeur de la clé. Chooseactivité.thief En utilisant la méthode getStringextra. La valeur obtenue que nous dérivons dans Affichage. (variable infotextview.). Si nous sommes retournés à l'écran via le bouton arrière, effacez simplement le texte.
Lors de la fermeture d'une filiale à l'intérieur du composant parent, le gestionnaire est déclenché onActivityResult (). Gestionnaire onActivityResult () Prend plusieurs paramètres.
- Code requis. Le code utilisé pour commencer l'activité renvoyant le résultat
- Code de résultat. Le code de résultat défini par la filiale et indiquant la fin de son travail. Il peut être une valeur entière, mais comme règle, soit Activité.Result_OK.Soit Activité.Result_canceled.
- Données. L'intention utilisé pour l'emballage des données retournées. En fonction de l'activité subsidiaire, il peut inclure le chemin URI représentant la partie sélectionnée du contenu. Alternativement (ou ajouts), la filiale peut renvoyer des informations sous la forme de valeurs simples emballées dans le paramètre Intention suppléments.
Si le travail d'activité subsidiaire s'est terminé imprévu ou si le code de résultat n'a pas été spécifié avant la fermeture, ce paramètre sera égal à Activité.Result_canceled..
Exécutez le projet, cliquez sur le bouton et allez sur le deuxième écran. Nous choisissons l'une des options. Si vous sélectionnez une corbillaille, l'écran se ferme et le nom du criminel apparaîtra sur le premier écran. Si vous choisissez une collation, son nom apparaîtra.
Au fait, si vous choisissez un chat, son nom n'apparaîtra pas! Vérifiez et voyez par vous-même. Vous allez demander pourquoi? Élémentaire Watson! Le criminel n'a pas examiné un détail important. Le restaurant a été observé au caméscope et le dossier a montré qui a réellement volé la saucisse et substitué le chat. Vaska, tiens-toi!
P.s. Si au début, il semblait incompréhensible, alors beaucoup plus clair avec beaucoup. La transmission de données entre les écrans est souvent trouvée dans les applications et vous ne lirez pas l'exemple plus d'une fois.
P.p.s. Meilleur poisson - saucisse. Connaissant cette faiblesse, il n'était pas difficile de substituer un chat.
Utiliser des filtres
Dans l'article, j'ai montré un moyen courant de transition vers une autre activité, quand dans la méthode startactivité () La classe actuelle et la classe pour la commutation sont indiquées. Au fait, la classe d'activité n'a pas à faire partie de votre application. Si vous connaissez le nom de la classe d'une autre application, vous pouvez y aller. Mais vous pouvez aller à une autre activité d'une autre manière.
En pratique, se réunit moins souvent, mais peut être utile. Supposons que vous ayez déjà la deuxième activité. Dans le manifeste, ajoutez un filtre spécial à celui-ci:
Et exécuter une seconde activité via un bouton Cliquez-il de cette façon.
Public Void OnClick (nouvel intention) (ru.alexanderklimov.estapplication.secondactivité "));)
Remplacer longue chaîne Sur la constante.
Public statique final String Action_second_activity \u003d "ru.alexanderklimov.estapplication.secondactivité"; Void public onclick (nouvelle intention (action_second_activity);)
Alors qu'est-ce que nous avons fait. Pour la deuxième activité, nous avons prescrit le filtre et indiqua le nom pour action. En attributions android: nom.. Pour plus de commodité, j'ai simplement placé le nom complet de l'activité avec le nom du paquet. Concepteur de classe Intention Il a plusieurs versions surchargées. Dans l'une des versions, vous pouvez spécifier une chaîne d'action. Nous avons indiqué notre action créée, qui est écrite dans la deuxième activité. Le système tout en travaillant en parcourant les manifestes de tous applications installées. Lors de la recherche de conformité, le système trouve notre filtre et commence l'activité souhaitée.
Par le même principe, d'autres activités peuvent être lancées. Regardez l'exemple. Si vous copiez un exemple sur vous-même et regardez la documentation pour android.provider.settings.acte_airplane_mode_settings.Vous verrez qu'une constante de chaîne correspond à ce code. public static final java.lang.string action_airplane_mode_settings \u003d "android.settings.airplane_mode_settings". Comparer avec notre code. Vous pouvez supposer que l'activité des paramètres pour régime autonome Cette chaîne est prescrite dans le filtre.
Nom de la catégorie Filtrer android.intent.category.default. Selon le système selon lequel l'action par défaut doit être effectuée, à savoir exécuter une activité. Il y a d'autres noms qui ne sont pas intéressés par nous.
Et maintenant, la question est sur le remblai. Que se passe-t-il si vous créez une autre activité et spécifiez le même filtre que la deuxième activité? Et vérifions. Créez une troisième activité et copiez le bloc avec un filtre de la deuxième activité.
Cliquez sur le bouton dans la première activité. Le système vous demandera de choisir l'option souhaitée.
Si vous sélectionnez Toujours, la prochaine fois que vous n'avez pas à choisir. Pour réinitialiser la sélection, accédez aux propriétés de l'application dans les paramètres et localisez le bouton. Effacer les valeurs par défaut..
Activité en cours d'exécution par son nom
Dans le concepteur Intention Le deuxième paramètre est la classe. Mais supposons qu'il existe une sorte de base de données, où les noms des activités sont indiqués et que nous devons exécuter l'activité nécessaire par son nom. Nous pouvons sur la base d'une variable de chaîne pour obtenir la classe elle-même et exécuter l'activité.
Essayez (// Nom complet de la classe d'activité String ActivityName \u003d "ru.alexanderklimov.testapplication.secondactivité"; // Recevez l'objet de la classe de classe> MyClass \u003d classe.forname (ActivityName); Intention intention \u003d nouvelle intention (ceci, myclass); Startactivité (intention); ) Catch (ClassNotFoundException E) (E.PrintStackTrace ();)