Comunicarea între activitate și servicii. Comutați între ecranele de aplicație Transmisia de date între activați
Cumva am avut o sarcină de a transfera date de la serviciu la Activat. Căutarea de soluții în SDK standard a început, dar deoarece nu a existat timp, apoi a zburat o soluție proastă ca utilizare a bazei de date. Dar întrebarea a fost deschisă și, după un timp am dat seama cu un mod mai corect, care este în SDK - folosind clasele de mesaj, manipulator, mesager.
Idee
Trebuie să transmităm date de la Activat la service și înapoi. Cum o facem? Pentru a rezolva sarcina noastră, avem deja tot ce aveți nevoie. Tot ce aveți nevoie este de a lega serviciul la atitudini folosind BindService, transferați parametrii doritori și un pic de magie sub forma utilizării claselor de mesaje. Și magia este de a utiliza variabilele instanței mesajului și, în special, răspunsul. Această variabilă este necesară pentru noi, astfel încât să putem face referire la instanța de service Messanger de la Activati \u200b\u200bși în serviciul către Messanger - o copie. De fapt, nu atât de simplu. Cel puțin pentru mine nu mintea mea cea mai talentată. În parte, am îmbunătățit documentația deja - servicii, de asemenea, există bun exemplu pe Stackoverflow. În orice caz, sper că articolul va fi de ajutor cel puțin pe cineva și nu am îndrăznit să nu îndrăznesc în zadar.
Exemplu
De exemplu, implementăm un serviciu care va crește și reduce valoarea contorului și va returna rezultatul în Activati \u200b\u200bîn Texwview. Codul de aspect este omis, pentru că există două butoane și un câmp de text - totul este simplu.
Vânzări
Voi da un cod complet activat:
Mainactivitatea clasei publice extinde activitatea (TESTSERVICECICECCONNECCONNN, TestTxtTxconnN; TestTxtTxt TESTTT; Messenger Final Messenger \u003d Messenger ToserviceMeger; @ eXervicee Public Oncreate (Bundle savedinstanceState) (Super. Oncreate (savetinstancestate); setContentView; testtxttbt \u003d (TextView) Findowbyid (R.Id.test_txt); BindService (New Intent), (TestServConn \u003d New TestServiceConnection ()), Context .bind_auto_create); SUPER.ONEGESTROY (); UNBINDSERVICICE (TestServConn); (MSG.RePlyto \u003d (MSG), ToserviceMeger.Senger (MSG), ToserviceMeger.Senger (MSG);) Catch (E.PrintSackTracce () ;)) Volumul public CountDeclock (butonul View) (Null, TestService.Count_minus); MSG .RePlyto. \u003d mesager; Încercați (Toservicemesenger.Send (MSG);) Catch (E.PrintSackTracce ();)) Clasa privată Incominghandler se extinde Manipulator (GetMeSsage Public Public (MSG) (Cazul TestService. Get_Count: log.d (etichetă "( Activitate) ... Obțineți numărul "); TestTxt.SetText (" "+ MSG.ARG1); Break;))) Clasa privată Certificare Conectare Conectare ServiceConecție (@ Evaluarea Publicului Public OnserviceConnected (Nume componentă, Serviciul IBINDER) (Toservicemesenger \u003d Messenger nou ; // trimite valoarea inițială a mesajului msg \u003d mesaj.obin contor (, testservice.set_count); msg.replyto \u003d mesager; msg.arg1 \u003d 0; // Contorul nostru de încercare (Toservicemesenger.Send (MSG);) Captura (RemoteException E) (E.PrintSckTrace ();)) @ eXoverride Public VOID Onservicedisconneed (nume ComponentName)))
Iti voi explica. Când creați activat, suntem imediat legați de serviciul, implementarea interfeței de service și trimiteți un mesaj la serviciul "Setați valoarea contorului", trecând zero și creând un ToserviceMessANGER, trecând interfața IBINDER la designer. Apropo, în serviciu este necesar să returnați acest ehemple, altfel va fi NPE. Cu această clasă, trimitem mesajul serviciului. Și aici este Magic - salvăm instanța noastră de mesager la variabila ReplyTo - cea care primește un răspuns de la server și este prin el care va comunica cu Activat.
Pentru a primi un mesaj de la serviciu, utilizați manipulatorul dvs. și doar căutați variabile de care avem nevoie și de a face acțiuni asupra lor. Prin clicuri de pe butoane (CounterinCrClick, Countdecrifick Methods), trimiteți cereri către serviciu, specificând acțiunea dorită în msg.what variabila.
Pachet com.example.servicetest; Import android.app.service; Import Android.Content. *; Importați Android.os. *; Import Android.os.process; Import Android.Util.log; Testservice de clasă publică extinde serviciul (Final Public Final Int_plus \u003d 1; Final Public Static INT Count_minus \u003d 2, Final Public Static Int Set_Count \u003d 0, Final Public Static Int_Count \u003d 3; INT Count \u003d 0; Incominghandler Indandler; Messenger Messanger; Messenger ToactivitateMessenger; @ evoluție publică publică @Override () (super.oncreate (); hairthread thread \u003d New horythread ("servicestargarii", proces.thread_prinity_background); fir.start (); inhandler \u003d nou de incredere (fir.Getlooper ()); Messanger \u003d Noul mesager (inhandler);) @ entuziasm Public Ibinder (retur Messanger.getbinder ();) @ intenție publică @ entuziasm (return start_sticky;) // Activități de manipulare a mesajelor clasa privată Incomingler extinde Handler (Super Looper) (Looper Looper) (Looper Looper) @ WholyMessage (Mesaj Mesaj MSG) (//super.handlemessage (msg); ToactivitateMess inginer \u003d msg.replyto; Comutator (msg.what \u003d msg.arg1; log.d (mainctivitate.tag "(serviciu) set"); pauză; pauză; caz_plus: numără ++; log.d (mainctivity.tag "(serviciu ) ... Count Plus "); Break; Break; caz_minus: log.d (Mainactivitate.tag" (serviciu) ... număr minus "); contesta-; rupe;) // trimiteți o valoare a contorului în mesajul de activativitate Outmsg \u003d mesaj.Obin (locuit, get_count); Outmsg.arg1 \u003d Count; outmsg.replyto \u003d mesanger; Încercați (dacă ToactivitateMessenger! \u003d Null) ToactivitateMessenger.Send (Outmsg);) captura (E.PrintSckTrace ();))))
Toate prin analogie cu logica în Activiti. Nici măcar nu știu dacă trebuie să explici ceva. Singurul moment este că trimit imediat o solicitare înapoi la Activat în Management, folosind variabila magică Reply pentru și trag mesagerul de mai sus de mai sus. Iar al doilea moment pe care l-am spus deja este:
@ Entuziasm Public IBIND (Intent ARG0) (return Messanger.getbinder ();)
fără de care totul cade. Această instanță de interfață va fi transmisă către serviceConectare.
Concluzie
În general, totul. Un astfel de exemplu controversat de interacțiune de activat și serviciu. Mi se pare că interacțiunea non-trivială este frumoasă, deși cineva poate părea altfel.
Întrebări, clarificări și altele în PM. Pot exista inexactități cu privire la orice aspect, deci nu ezitați să scrieți și să îndreptați.
Sper că postul a fost util cititorilor.
Ultima actualizare: 04/03/2018
Pentru a transfera date între două activități, se utilizează un obiect de intenție. Prin metoda Putextra (), puteți adăuga cheia și valoarea asociată.
De exemplu, transmiterea din activitatea curentă în secretul "Hello World" cu cheia "Bună ziua":
// crearea unui obiect de intenție pentru lansarea secundarului intens intens \u003d Intenție nouă (aceasta, secundare.class); // transferul unui obiect cu cheia "Hello" și valoarea "Bună ziua" a intenției.putextra ("salut", "salut"); // începerea startactivității secundare (intenție);
Metoda Putextra () este utilizată pentru a transmite date, care, ca valoare, vă permite să transferați cele mai simple tipuri de date de tip - șir, Int, float, dublu, lung, scurt, octet, char, garniturile acestor tipuri sau Obiect de interfață serializabil.
Pentru a obține datele trimise la încărcarea secundarului, puteți utiliza oBȚINE.(), în care obiectul este transmis:
Bundle argumente \u003d Getintent (). Getextras (); String name \u003d argumentes.get ("salut"). TOSTRING (); // Salut Lume.
În funcție de tipul de date trimise, când este primit, putem utiliza un număr de metode de obiecte de pachete. Toate acceptă cheia obiectului ca parametru. Principalele sunt:
obține (): metoda universalăcare returnează valoarea tipului de obiect. În consecință, câmpul de primire trebuie convertit la tipul dorit
getString (): Returnează șirul de tip obiect
getint (): Returnează valoarea tipului INT
gETBYTE (): Returnează valoarea tipului de octeți
getchar (): Returnează valoarea tipului de caractere
getshort (): returnează o valoare de tip scurt
getLong (): Returnează o valoare lungă
getfloat (): returnează valoarea tipului float
getDouble (): Returnează o dublă valoare
getboolean (): Returnează o valoare de tip boolean
getcharary (): Returnează o serie de obiecte char
getInTranray (): Returnează o serie de obiecte int
getflotaRray (): Returnează o serie de obiecte plutitoare
getSerializable (): Returnează obiectul de interfață serializabil
Lăsați-ne în proiect vom fi definite două activități: mainctivitate și secundare.
În codul secundar vom determina obținerea datelor:
Pachet com.example.eugene.serializeApp; Importați Android.support.v7.app.appCompatitactivitate; Import Android.os.Bundle; Import Android.Widget.TexView; Clasificarea clasa publică extinde AppCompatibilitatea (@ VIDUL PROTEJAT PROTECTAT (Bundle SavesinstanceState) (Super.oncreate (SavedinstanceState); TexView TexView \u003d New TexView (acest); TextView.settextsize (20); TextView.setpadding (16, 16, 16, 16 ); Bundle Argumente \u003d Getintent (). Gtextras (); dacă (argumente! \u003d Null) (String Name \u003d Argments.Get). Totostring (); String Company \u003d argumente.getststring ("companie"); int preț \u003d argumente. Getint ("Preț"); TextView.settext ("Nume:" + Nume + "\\ nCompany:" + Company + "\\ nPrice:" + preț);) SetContentview (TextView);))
În acest caz, în second-le primim toate datele din obiectul pachetului și afișați-le în caseta TextView TextView. Se presupune că această activitate va fi transmisă trei elemente - două rânduri cu numele și cheile companiei și o cheie cu un preț-cheie.
Acum vom defini transferul la secretația datelor. De exemplu, definim următoarea interfață pentru mainctivitatea în dosarul Activitate_main.xml:
Iată trei câmpuri de text pentru introducerea datelor și un buton.
În clasa de reactivitate definim următorul cuprins:
Pachet com.example.eugene.serializeApp; Import android.content.Intent; Importați Android.support.v7.app.appCompatitactivitate; Import Android.os.Bundle; Import Android.view.view; Import Android.widget.editText; Mainactivitatea clasei publice extinde AppCompatitatitatea (@ Super.OncRestanceState (Super.OncRestanceState); SetContentView (R.Layout.Activity_main);) Vizualizare publică (Vizualizare v) (Vizualizare v) (Vizualizare V) (Final EditText NameText \u003d Grăbește .Name); Final EditText CompanyText \u003d FindowByID (R.Id.COMPANY); Final EditText Prictext \u003d FindowByid (R.Id.Price); String Name \u003d NameText.Getttext (). Tostring (); String Company \u003d COMPANYText.gettext ( ) .TOSTRING (); INT Price \u003d INTEGERT.GETTEXT (PRICTEXT.GETTEXT (). TOSTRING ()); intens intens \u003d Intenție nouă (aceasta, secundActivitate.class); intenție.putextra ("nume", nume); intenție. Putextra ("Compania", Company); Intent.putextra ("preț", prețul); Startactivitatea (intenția)))
În butonul apăsând butonul, obțineți datele introduse în câmpuri de text, date și le transmiteți obiectului intenționat utilizând metoda Putextra (). Apoi lansați secundarea.
Ca rezultat, atunci când faceți clic pe butonul pornește secretația, care va primi date introduse în câmpurile de text.
Transferul obiectelor complexe
În exemplu, datele simple au fost transmise - numere, linii. Dar putem transmite, de asemenea, date mai dificile. În acest caz, se utilizează mecanismul de serializare.
De exemplu, permiteți-ne în proiect să fie definită de clasa de produs:
Pachet com.example.eugene.serializeApp; Importați java.io.serializabil; Produsul de clasă publică implementează serializable (nume de șir privat; companie de șir privat; Private int pret; produs public (nume de șir, companie de șir, int preț) (numead.name \u003d nume; acest.robrice \u003d companie; acest.rice \u003d pret; Stringul public GetName () (numele de returnare;) Set nume de viduri publice (nume de șir) (nume.name \u003d nume;) Stringul public GetCompany () (companie de rentabilitate;) Vulie publică SetCompany (Compania String) (Compania de șir) Public Int GetPrice () (prețul de returnare;) Vulie publică SETPRICE (INT Preț) (Acest.robice \u003d;))
Este demn de remarcat faptul că această clasă implementează interfața serializabilă. Acum veți schimba codul de reactivitate:
Pachet com.example.eugene.serializeApp; Import android.content.Intent; Importați Android.support.v7.app.appCompatitactivitate; Import Android.os.Bundle; Import Android.view.view; Import Android.widget.editText; Mainactivitatea clasei publice extinde AppCompatitatitatea (@ Super.OncRestanceState (Super.OncRestanceState); SetContentView (R.Layout.Activity_main);) Vizualizare publică (Vizualizare v) (Vizualizare v) (Vizualizare V) (Final EditText NameText \u003d Grăbește .Name); Final EditText CompanyText \u003d FindowByID (R.Id.COMPANY); Final EditText Prictext \u003d FindowByid (R.Id.Price); String Name \u003d NameText.Getttext (). Tostring (); String Company \u003d COMPANYText.gettext ( ) .TOSTRING (); INT Price \u003d Integer.Parsext (PRICTEXT.GETTEXT (). TOSTRING ()); Produs produs \u003d Produs nou (nume, companie, preț); Intenția intenției \u003d Intenția nouă (aceasta, second-lei.class); Intennt.putextra (produs.class.getsimplename (), produs); StartCivitate (intenție)))
Acum, în loc de trei date împrăștiate, un obiect de produs este transmis. Ca o cheie, rezultatul este rezultatul metodei produsului.class.getsimplename (), care se întoarce, în esență, numele clasei.
Și schimbați clasa Secrepitanty:
Pachet com.example.eugene.serializeApp; Importați Android.support.v7.app.appCompatitactivitate; Import Android.os.Bundle; Import Android.Widget.TexView; Clasificarea clasa publică extinde AppCompatibilitatea (@ VIDUL PROTEJAT PROTECTAT (Bundle SavesinstanceState) (Super.oncreate (SavedinstanceState); TexView TexView \u003d New TexView (acest); TextView.settextsize (20); TextView.setpadding (16, 16, 16, 16 ); Bundle Argumente \u003d Getintent (). GETEXTRAS (); produsul final produs; dacă (argumente! \u003d Null) (produs \u003d (produs) argumente.getserializable (produs.class.getsimplename ()); textView.settext ("Nume: "+ Produs.GetName () +" \\ nCompany: "+ produs.GetCompany () +" \\ nPrice: "+ string.Valueof (produs.getprice ()));) SetContentview (TextView);))
Metoda GetSerializabil () este aplicată pentru a obține date, deoarece clasa de produse implementează interfața serializabilă. Astfel, putem transmite un singur obiect în loc de apelarea datelor disparate.
Buna ziua.
Trebuie să transmiteți datele obținute prin intermediul activității. Acest lucru se poate face prin crearea unui flux în activitate în care să se organizeze În timp ce ciclul (! ISIntru ()) și trimiteți date din tamponul UART. După aceea, prin apelarea fluxului de activitate a UI - mainctivitate.Acestia (noua runnable (), efectuați acțiunile necesare cu această activitate. Dar dacă numim altă activitate din activitatea principală, atunci firul organizat nu permite transmiterea Datele către activitatea recent creată. Dacă înțeleg corect, astfel încât datele din flux pot fi transferate la orice activitate, fluxul trebuie creat nu în activitate, ci în serviciu.
Întrebare: UAR a primit date, în flux (care este creat în serviciu), este necesar să se transfere date la activitate, care este acum activă, cum se poate face acest lucru și este făcut deloc?
1 răspuns
În fiecare activitate, creați manipulator. În metoda Onresume (), această activitate face legătura (). Acolo, unul dintre parametri este comunicarea de interfață. Implementarea este cel puțin aceeași activitate. Implementați în acesta onserviceconectat (). În acest apel, unul dintre parametri vine la serviciul însuși. Așa că sunați la Sethandler () de la acest serviciu. Treceți manipulatorul acolo, care este în activitatea curentă. Și aici sunt datele primite despre aruncarea UART în serviciul acestui manipulator. Apropo, manipulator lucrează în mod tradițional în firul principal, deci nu va fi necesar să se efectueze RunonuiTited.
Aplicația nu este întotdeauna compusă dintr-un singur ecran. De exemplu, am creat foarte mult program util Și vreau să cunosc utilizatorul care este autorul său. El presează butonul "Despre programul" și cade pe ecran nouÎn cazul în care informații utile despre versiunea programului, autorul, adresa site-ului, câte pisici de la autor etc. Performați ecranul de activitate ca o pagină web cu un link către o altă pagină. Dacă vă uitați la codul din fișier MAINActivitate.java. Din lecțiile trecute, veți vedea că clasa noastră Activitate principala. se referă, de asemenea Activitate (sau moștenitorii lui) sau, dat, mai precis, moștenită de la el.
Mainactivitatea clasei publice extinde AppCompatiția
Deoarece este ușor de ghicit, ar trebui să creăm o nouă clasă, care poate fi similară Activitate principala. Și apoi comutați cumva la el când apăsați butonul.
Pentru experiment, vom lua programul de la prima lecție și vom folosi butonul pentru experimente (sau vom crea un proiect nou cu un singur buton pe ecran). Apoi, creați un formular nou pentru a fi afișat. informatii utile. De exemplu, arătați utilizatorului care face o pisică când merge la stânga și la dreapta. Sunt de acord că este foarte informații importantedând cheia universului neclar.
Crearea unei noi activități va fi manual, deși în studio există Șabloane gata. Dar nu este nimic complicat și pentru o mai bună înțelegere este utilă pentru a face totul cu mâinile voastre.
Creați un nou fișier XML Markup activitate_about.xml. în dosar res / aspect.. Faceți clic dreapta pe dosar aspect. și selectați din meniul contextual Nou | Fișier de resurse layout.. Apare o casetă de dialog. În primul câmp introduceți numele fișierului activitate_bout. În al doilea rând, trebuie să introduceți elementul rădăcină. Implicit acolo există Constrângeri.. Spălăm textul și introducem De scriere.. Introducerea mai multor caractere este suficientă pentru ca studioul să sugereze opțiuni gata făcute, puteți apăsa imediat Enter, fără a aștepta cuvântul Intrare completă:
Se oprește billetul corespunzător în care elementul va introduce elementul TextView..
Informațiile vor fi eliminate din resurse, și anume de la o resursă de șir. gray_text.. Acum este evidențiată în roșu, semnalizând despre absența informațiilor. A fost posibil să faceți clic pe ALT + ENTER. Și introduceți text în caseta de dialog. Dar pentru exemplul nostru, această metodă nu se va potrivi, deoarece textul nostru va fi multiplay, folosind caractere de control. Prin urmare, procedați într-un mod diferit. Deschide fișierul res / valori / strings.xml Și introduceți manual următorul text:
Am folosit cele mai simple etichete de formatare a textului HTML , , . Pentru exemplul nostru, este suficient să evidențiem cuvintele grase care aparțin pisicii și direcției de mișcare. Pentru a transfera textul la Șir nou Utilizați simboluri \\ N.. Adăugați o altă resursă de șir pentru antetul noului ecran:
Marcarea a dat seama. În continuare trebuie să creați o clasă pentru fereastră Inovalitate.java.. Selectați în meniu Fișier | Nou | Clasa Java. și umpleți câmpurile potrivite. La început, este suficient să specificați numai numele. Apoi dezastru cu alte câmpuri.
Avem piesa de prelucrat.
Acum, clasa este aproape goală. Adăugați codul manual. Clasa trebuie să fie moștenită din clasa abstractă Activitate sau rudele sale ca Fragmentectivitate., AppRompatactivity. etc. finalizarea extinde activitatea.. Clasa de activitate ar trebui să aibă o metodă oncreate (). Am pus cursorul mouse-ului în interiorul clasei și alegem în meniu Cod | Metode de suprascriere. (Ctrl + O). În caseta de dialog Căutăm clasa dorită, puteți apela primele caractere pentru a căuta rapid pe tastatură. În metoda creată, trebuie să apelați metoda setContentView ()care va încărca marcajul pregătit pe ecran. Vom avea această opțiune.
Pachet ru.alexanderklimov.helloworld; Import Android.app.Activity; Import Android.os.Bundle; / ** * Creat de Alexander Klimov la 01.12.2014. * / Clasa publică Detalii extinde activitatea (savetinstanstanceState); SetContentView (R.Layout.Activitate_about);))
Acum începe cel mai important lucru. Sarcina noastră este să mergeți la un nou ecran când faceți clic pe butonul de pe primul ecran. Du-te înapoi la clasă Activitate principala.. Scriem un clic pe Handler Click:
Publicul public onClick (întreprindere.Această, inactivitate.class); Startactivitate (intenție);)
Aici am folosit o modalitate de a gestiona butonul apăsând despre care a fost spus în clasă.
Pentru a începe un nou ecran, trebuie să creați o instanță de clasă. Intention. și specificați clasa curentă în primul parametru, iar în al doilea - clasa pentru tranziție, o avem Inactivitate.. După aceea, se numește metoda startactivitate ()care lansează un nou ecran.
Dacă încercați acum să verificați funcționarea aplicației în emulator, atunci veți primi un mesaj de eroare. Ce am greșit? Am pierdut un pas important. Trebuie să înregistreze noi Activitate În Manifesto. Androidmanifest.xml.. Găsiți acest fișier în proiectul dvs. și faceți clic pe acesta de două ori. Se deschide o fereastră de editare a fișierelor. Adăuga etichetă nouă
Astfel încât resursa de șir a fost utilă. despre_title.. Rulați aplicația, faceți clic pe buton și obțineți o fereastră Despre program. Așa că am învățat cum să creăm o fereastră nouă și să o numim pentru a face clic pe buton. Și la dispoziția noastră a apărut un program Megaudobal - acum va fi întotdeauna un indiciu la îndemână, ceea ce face o pisică când merge mai departe.
Mă uit din nou că cea de-a doua clasă de activitate creată ar trebui să fie moștenită din clasă Activitate sau el ca ( Listactivitate. etc.), aveți un fișier XML Markup (dacă este necesar) și să fie înregistrat în manifestat.
După ce ați apelat metoda startactivitate () Va fi lansată o nouă activitate (în acest caz Inactivitate.), va fi vizibil și se deplasează în partea superioară a stivei care conține componentele de lucru. Când sună o metodă fINALIZAREA () Din noua activitate (sau când apăsați tasta hardware de retur), acesta va fi închis și eliminat din stivă. Dezvoltatorul se poate trece, de asemenea, la activitatea anterioară (sau la oricare) utilizând aceeași metodă startactivitate ().
Creați un al treilea ecran - o modalitate pentru leneș
Programatorii, ca pisici, sunt creaturi leneșe. Amintiți-vă constant că pentru activitatea trebuie să creați o marcă și o clasă care este moștenită de la Activitate, și apoi nu uitați să înregistrați clasa în Manifesom - da, Nafig.
În acest caz, selectați în meniu Fișier | Nou | Activitate | Activitate de bază (sau alt șablon). Mai mult, va apărea o fereastră familiară pentru crearea unei noi activități. Completați câmpurile necesare.
Faceți clic pe buton FINALIZAREA Iar activitatea va fi gata. Pentru a vă asigura că deschideți fișierul manifest și verificați disponibilitatea. noua înregistrare. Nu mai spun despre fișierele clasei și despre marcaj, vor apărea în fața dvs.
Alone adăugați buton nou În ecranul principal de activitate și scrie codul pentru trecerea la activitatea creată.
La început, vă sfătuiesc să creați manual toate componentele necesare pentru noua activitate pentru a înțelege relația dintre clasă, marcaj și manifest. Și când aveți o mână, puteți folosi expertul de creație a activității pentru a accelera munca.
Transmiterea datelor între activități
Noi am folosit cel mai simplu exemplu Pentru a apela un alt ecran de activitate. Uneori este necesar nu numai să apelați un nou ecran, ci și să transferați date. De exemplu, numele de utilizator. În acest caz, trebuie să utilizați o zonă specială extradata.care este disponibil la clasă Intention..
Regiune extradata. - Aceasta este o listă de cupluri valoare cheiecare este transmisă împreună cu intenția. Liniile sunt folosite ca taste și pentru valori Puteți utiliza orice tipuri de date primitive, matrice primitive, obiecte de clasă Pachet. si etc.
Pentru transferul de date la o altă metodă de activitate este utilizată putextra ():
Intennt.putextra ("cheie", "valoare");
Activitatea de activitate ar trebui să provoace o metodă adecvată: getIntextra (), getStringextra () etc.:
Int numărare \u003d getintent (). GetIntextra ("nume", 0);
Remaimm exemplul anterior. Avem deja trei activități. La prima activitate vor fi plasate două câmpuri de text și un buton. Aspect Pot fi după cum urmează:
În cea de-a doua activitate Secundar. Element de instalare TextView.unde vom afișa textul obținut din prima activitate. Scriem următorul cod pentru metodă oncreate () În a doua activitate.
@ VIDE PROTECTATE PROTECTATE (Bundle SavesinstanceState) (Super.Oncreate (SavesinstanceState); SetContentView (R.Layout.Activity_Second); șir "Zhyvotryh"; șir cadou \u003d "gaură gaură"; TexView InfotexView \u003d (TexView) .Id.textviewInfo); InfotextView.settext (utilizator + ", ați fost trimis" + cadou);)
Dacă porniți programul acum și pur și simplu apelați la a doua fereastră, așa cum este descris în prima parte a articolului, vom vedea inscripția implicită Îngălbenit, ai trecut o gaură de la Bagel. Sunt de acord, este destul de ofensator să primiți astfel de mesaje.
Am rezolvat situația. Adăugați codul de la prima activitate:
Public VOID ONCLICK (Vizualizare Vedere) (EditText UseRedittext \u003d (EditText) FindowViewByid (EditText GiftextText \u003d (EditText) FindTestttext \u003d (EditText) FindowViestyyid (R.Id.editTextgift); Intent Intent \u003d Intenție nouă (mainctivitate. Acest, secundare. Clasa); // În cheia de utilizator, veți primi textul PIAM de la primul câmp de text Intent.putextra ("Utilizator", UserTTTEXT.GETTEXT (). TOSTRING ()); // B The Key Gift Piham din cel de-al doilea câmp text Intennt.putextra ("cadou", giftedittext.gettext (). Tostring ()); startactivitate (intenție);
Am plasat într-un container de obiecte speciale Intention. Două chei cu valori care sunt luate din câmpurile de text. Când utilizatorul introduce date în câmpuri text, acestea vor cădea în acest container și vor fi transferate în a doua activitate.
A doua activitate ar trebui să fie pregătită pentru o primire caldă a mesajelor după cum urmează (grasimi evidențiate).
// Valori implicite șirul de utilizator "" galben "; Șir cadou \u003d "gaura din bule"; utilizator \u003d getintent (). getextras (). GetString ("nume de utilizator"); Cadou \u003d getintent (). Getextras (). Getstring ("cadou"); TextView InfotexView \u003d (TextView) FindowviewiD (R.Id.textviewInfo); InfotexView.settext (utilizator + ", ați fost trimis" + cadou);
Acum mesajul nu arată așa, ci chiar plăcut pentru cineva. În exemple dificile, este de dorit să se adauge un control la procesarea datelor. Există situații în care executați a doua activitate cu tipul de date goale nULCeea ce poate duce la prăbușirea cererii.
În cazul nostru, știm că așteptăm o valoare a șirului, astfel încât codul poate fi rescris:
Intenția intenționată \u003d getintent (); utilizator \u003d intennt.getstringextra ("numele de utilizator");
Utilizator \u003d getintent (). Getstringextra ("nume de utilizator");
Programul are un dezavantaj - nu este clar de la care suntem LED-uri. Orice mentă bine adusă nu va lua un cadou de la o sursă anonimă. Prin urmare, ca o temă, adăugați o altă casetă de text pentru a introduce numele utilizatorului care trimite mesajul.
Google recomandă utilizarea următorului format pentru taste: numele pachetului dvs. ca prefix și apoi cheia în sine. În acest caz, puteți fi încrezători în unicitatea cheii atunci când interacționați cu alte aplicații. Aproximativ:
Public final Static String Utilizator \u003d "ru.alexanderklimov.myapp.user";
Care a pus pisica vaska - obține rezultatul înapoi
Nu se întâmplă întotdeauna să transmită pur și simplu aceste alte activități. Uneori trebuie să obțineți informații din altă activitate atunci când este închisă. Dacă am folosit metoda startanive (intenția intenției)Apoi există o metodă relativă startoryInForresult (intenția intenționată, solicitarea INT). Diferența dintre metode este parametru suplimentar Codul de solicitare.. De fapt, este doar un număr întreg pe care îl puteți gândi la voi înșivă. Este necesar pentru a distinge de la care a venit rezultatul. Să presupunem că aveți cinci ani ecrane suplimentare Și le atribuiți valori de la 1 la 5 și pe acest cod puteți determina al cărui rezultat trebuie să procesați. Puteți utiliza -1, atunci va fi echivalentă cu apelul metodei startactivitate (). Nu voi obține nici un rezultat.
Dacă utilizați metoda startierieiForresult ()Trebuie să înlocuiți metoda din codul pentru primirea rezultatului onactivitateResult () și procesați rezultatul. Confuz? Să ne întrebăm exemplul.
Să presupunem că sunteți un cerb. Au fost primite informații că două bucăți de cârnați și alte produse au fost furate de la restaurantul din tabelul unei persoane influente. Suspuage Palo pe trei suspecți - Crow, păsărică și pisică pisică.
Unul dintre vizitatori a oferit o serie de fotografii de pe praful său iPhone:
Există, de asemenea, o indicație a unui alt martor: Și Vaska ascultă, da mănâncă.
Creați un nou proiect Sherlock. Cu două activități. Pe primul ecran va fi un buton pentru a comuta la al doilea ecran și eticheta de text în care va fi afișat numele hoțului.
Pe al doilea ecran va fi un grup de întrerupătoare:
De când ne vom aștepta la un răspuns de la al doilea ecran, trebuie să folosim metoda startierieiForresult () Pe primul ecran în care vom da o variabilă Alege_Thief. ca parametru Codul de solicitare..
Final static privat în Alege_Thief \u003d 0; Public VOID ONCLICK (View V) (Mainectivity.Acestie, SangeActivitys.class); StartCalitateForresult (chestionent, selecție_ThFEF);)
Uită-te la cod. Când faceți clic pe buton, vom lucra cu al doilea ecran Alegereactivitate. Și lansați al doilea ecran cu așteptările rezultatului.
Mergeți la al doilea ecran și veți scrie codul pentru a doua activitate.
Final Final Static Thief \u003d "ru.alexanderklimov.sherlock.Thief"; Public Void Onradioclick (View V) (Intent Answerintent \u003d Intenție nouă (); comutator (V.GeTID () () ()) (caz R.Id.radiodog: AnswerIntent.putextra (hoț, "păsărică"); pauză; caz r.Id .radiocrow: AnswerIntent.putextra (hoț, "cioară"); pauză; caz r.id.radiocat: răspunsIntent.putextra (hoț, calul lui przhevalsky "); pauză, implicit: pauză;) setresult (rezultat_ok, răspuns contract); finisare ();)
Aici totul este simplu atunci când detectivul alege numele criminalului, apoi prin metodă putextra () Trecem numele cheie și valoarea acestuia.
Pentru confort, după selectarea, închidem imediat cea de-a doua fereastră și transmitem valoarea înainte de închidere. Rezultat_ok.astfel încât a fost clar că alegerea este făcută. Dacă utilizatorul închide ecranul prin intermediul butonului din spate, atunci valoarea va fi transmisă Rezultat_randled..
Metodă sETRESULT () Ia doi parametri: codul rezultat și rezultatul în sine prezentat sub formă de intenție. Codul rezultat sugerează că rezultatul a încheiat lucrarea de activitate, de regulă, fie Activitate.result_ok.fie Activitate.result_candled.. În unele cazuri, trebuie să utilizați propriul cod de rambursare pentru procesarea opțiunilor specifice pentru opțiunile de aplicare. Metodă sETRESULT () Suportă orice valoare întregă.
Dacă transmiteți date în mod clar prin intermediul butonului, ar fi plăcut să adăugați o metodă fINALIZAREA ()Pentru a închide a doua activitate ca fiind inutilă. Dacă tranziția apare prin butonul din spate, nu este necesar să faceți acest lucru.
Dacă activitatea a fost închisă de utilizator când este apăsat butonul de revenire a hardware sau dacă este metoda fINALIZAREA () a fost cauzată mai devreme decât metoda sETRESULT ()Codul rezultat va fi instalat în Rezultat_randled., iar intenția de întoarcere va arăta valoarea nUL.
Reveniți la primul ecran. Primul ecran așteaptă un răspuns de la al doilea ecran, deci trebuie să adăugați la metoda de cod onactivitateResult ().
@ Recomandări protejate @Overtridă (INT solicitare, INT rezultatul, date de intenție) (Super.onactivitateResult (solicitare de codificare, cod de referință, date); TexView InfotexView \u003d (TexView) FindowByID (R.Id.textviewInfo); dacă (solicitareCode \u003d\u003d alege_ThFEFF) ( dacă (rezultatulDOODE \u003d\u003d rezultat_ok) (String Thiefname \u003d Data.getStringTextra (SangeActivity.Thief); InfotexView.settext (ThiefName);) Alte (InfotexView.settext ("); // ștergem textul))
Metoda așteaptă datele primite cu codul. Alege_Thief.și dacă astfel de date sosesc, apoi recuperează valoarea de la cheie COSELLActivitate.Thief. Folosind metoda getStringTextra.. Valoarea obținută pe care o derivăm TextView. (variabil infotexView.). Dacă ne-am revenit la ecran prin intermediul butonului din spate, apoi ștergeți pur și simplu textul.
La închiderea unei filiale în interiorul componentei părinte, manipulatorul este declanșat onactivitateResult (). Handler. onactivitateResult () Ia mai mulți parametri.
- Codul de solicitare. Codul care a fost utilizat pentru a începe activitatea returnând rezultatul
- Codul de rezultat. Codul de rezultat stabilit de filială și indicând modul în care sa încheiat activitatea sa. Poate fi o valoare întregă, dar, de regulă, fie Activitate.result_ok.fie Activitate.result_candled.
- Date. Intenția utilizată pentru ambalarea datelor returnate. În funcție de scopul activității subsidiare, acesta poate include calea URI reprezentând partea selectată a conținutului. Alternativ (sau adăugiri), filiala poate returna informații sub formă de valori simple ambalate în parametrul de intenție in plus.
Dacă activitatea de activitate subsidiară sa încheiat neprevăzută sau dacă codul de rezultat nu a fost specificat înainte de închidere, acest parametru va fi egal cu Activitate.result_candled..
Rulați proiectul, faceți clic pe buton și mergeți la al doilea ecran. Alegem una dintre opțiuni. Dacă selectați un ciori, ecranul se închide și numele criminalului va apărea pe primul ecran. Dacă alegeți o gustare, atunci va apărea numele acestuia.
Apropo, dacă alegeți o pisică, atunci numele său nu va apărea! Verificați și vedeți-vă singur. Veți întreba de ce? Elementary Watson! Criminalul nu a considerat un detaliu important. Restaurantul a fost observat de la camera video, iar înregistrarea a arătat cine a furat de fapt cârnați și a substituit pisica. Vaska, ține-te!
P.S. Dacă la început se părea incomprehensibil, apoi mult mai clar cu mult. Transmisia de date între ecrane este adesea găsită în aplicații și nu veți citi exemplul de mai multe ori.
P.P.S. Cel mai bun pește - cârnați. Cunoscând această slăbiciune, nu a fost dificil să se înlocuiască o pisică.
Utilizați filtre
În articol, am arătat o modalitate comună de a trece la o altă activitate, când este în metodă startactivitate () Clasa și clasa actuală pentru comutare sunt indicate. Apropo, clasa de activitate nu trebuie să facă parte din aplicația dvs. Dacă știți numele clasei dintr-o altă aplicație, puteți merge la el. Dar puteți merge la o altă activitate într-un alt mod.
În practică, se întâlnește mai rar, dar poate veni la îndemână. Să presupunem că aveți deja a doua activitate. În Manifest, adăugați un filtru special:
Și să rulați a doua activitate printr-un buton clic în acest mod.
Publicul public onClick (New Intent) (Ru.Alexanderklimov.testApplication.Secondactivity "));)
A inlocui Șir lung. Pe constanță.
Publicul static Final String Action_Second_Activity \u003d "Ru.Alexanderklimov.testApplication.Secondacy"; Publicul public onClick (noua intenție (acțiune_second_activitate);)
Deci, ce am făcut. Pentru a doua activitate, am prescris filtrul și am indicat numele pentru acțiune. În atribut android: Numele.. Pentru comoditate, am plasat pur și simplu numele complet de activitate cu numele pachetului. Clasa designer. Intention. Are mai multe versiuni supraîncărcate. Într-una din versiuni, puteți specifica un șir de acțiune. Am indicat acțiunea noastră creată, care este scrisă în a doua activitate. Sistemul în timp ce lucrează navigarea manifestărilor tuturor aplicații instalate. Când căutați conformitatea, sistemul găsește filtrul nostru și începe activitatea dorită.
Cu același principiu, pot fi lansate alte activități. Uita-te la exemplu. Dacă copiați un exemplu pentru dvs. și uitați-vă la documentația pentru android.provider.Settings.Action_airplane_mode_settings.Veți vedea că o constantă de șir corespunde acestui cod. public Static Final Java.Lang.String action_airplane_mode_settings \u003d "android.settings.wasplane_mode_settings". Comparați cu codul nostru. Puteți presupune că activitatea de setări pentru regim autonom Acest șir este prescris în filtru.
FILTER Categorie Nume android.Intent.Category.default. Spune că sistemul pe care ar trebui să îl efectueze acțiunea implicită, și anume, să funcționeze activitatea. Există și alte nume care nu sunt interesate de noi.
Și acum întrebarea este pe fundul fundului. Ce se întâmplă dacă creați o altă activitate și specificați același filtru ca a doua activitate? Și să verificăm. Creați o a treia activitate și copiați blocul cu un filtru de la a doua activitate în ea.
Faceți clic pe butonul din prima activitate. Sistemul vă va cere să alegeți opțiunea dorită.
Dacă selectați Mereu, data viitoare când nu trebuie să alegeți. Pentru a reseta selecția, accesați proprietățile aplicației din setări și localizați butonul. Clar defaults..
Activitatea de desfășurare a numelui său
În designer Intention. Al doilea parametru este clasa. Dar să presupunem că există o bază de date, unde sunt indicate numele activităților și trebuie să conducem activitatea necesară prin numele său. Putem pe baza unei variabile de șir pentru a obține clasa însăși și a rula activitatea.
Încercați (// Numele complet al clasei de activitate de activitate Activitate \u003d "Ru.Alexanderklimov.testApplication.Secondactivity"; // primiți obiectul de clasă de clasă> Myclass \u003d clasa.forname (domeniu de activitate); Intent Intent \u003d Intenție nouă (aceasta, Myclass); Startactivitate (intenție); ) Captura (clasaNotfoundException e) (E.printSckTrace ();)