Kontakty

Komunikácia medzi činnosťou a službou. Prepínanie medzi aplikačnými obrazovkami prenosu dát medzi Activeti

Nejako som mal úlohu preniesť dáta zo služby do Activu. Vyhľadávanie riešení v štandardnom SDK začalo, ale keďže neexistoval čas, potom odletel zlé riešenie ako databázové použitie. Ale otázka bola otvorená a po nejakom čase som prišiel na správnejšiu cestu, ktorá je v SDK - pomocou tried správ, handler, messenger.

Nápad

Musíme prenášať údaje z aktivácie do služby a späť. Ako to robíme? Ak chcete vyriešiť našu úlohu, už máme všetko, čo potrebujete. Všetko, čo potrebujete, je viazať servis na zmiernenie pomocou Bindservice, preneste požadované parametre a trochu mágie vo forme používania tried správ. A mágia je použitie premenných inštancií správ a najmä odpoveďou. Táto premenná je pre nás potrebná, aby sme mohli poukázať na inštanciu služby Messanger z Activeti a v službe na Messanger-kópiu. V skutočnosti nie je to tak jednoduché. Aspoň pre moju nie na najvyvešenejšiu myseľ. Zároveň zlepšujem dokumentáciu, ktorá už je - Služby dobrý príklad na stackoverflow. V každom prípade dúfam, že článok bude užitočný aspoň niekým a ja som sa neodvážil, že nie zbytočne.

Príklad

Ako príklad, implementujeme službu, ktorá zvýši a znižuje hodnotu počítadla a vráti výsledok aktivity v textovom zozname. Kód rozloženia je vynechaný, pretože existujú dve tlačidlá a textové pole - všetko je jednoduché.

Predaja

Dám plne Activat kód:

MAKINAKTORÁ TRIEDA TRIEDA TRIEDA TRIEDAVA AKTIVITY (Public Static Final String Tag \u003d "TestService"; TestserviceConnection Testserconn; TextView TestTXT; Konečný Messenger Messenger \u003d Nový Messenger (Nový NESPRÁVNYHOBUDE (). OnCreate (Savedinstancestate); SETCONTENTVIEW; TestTextText \u003d (TextView) FindViewBed (R.id.test_txt); Bindservice (Nový zámer), (testservconn \u003d Nové testserviceConnection ()), kontext .bind_auto_create);) @override Public Void Onestroy () super.ondestroy (); Unbedservice (testservconn);) Public Void CountInCRCLIK (Tlačidlo Zobraziť) (NULL, testservice.count_plus); Msg.ReplyTice \u003d Messenger; vyskúšať (ToserviceMessenger.send (MSG);) Úlovok (napr. ;)) Public Void CountDecrClick (Tlačidlo zobrazenia) (NULL, testservice.count_minus); msg .Replyto. \u003d posol; Skúste (ToserviceMessenger.send (MSG);) Úlovok (E.printstacktrace ();)) SÚKROMNÁ TRIEDA TRIEDA NAJVYŠŠIACHUJÚCIU SÚKROMNÁ TRIEDA TRIEDY SÚKROMNÁ TRIEDA Aktivita) ... Získajte počet "); Testtxt.Settext (" "+ msg.arg1); Break;)))) SÚKROMNÁ TRIEDA TRIEDY TRUHYVERIČNÁCIECNOSTI Účinky Služby (@overnide Public Void OnserviceConnected (Názov komponenty, iBinder Service) (ToserviceMessenger \u003d Nový Messenger) ; // Odoslať počiatočnú hodnotu správy Msg \u003d správa.Orobtain counter (, testservice.set_count); msg.Replyto \u003d messenger; msg.arg1 \u003d 0; // náš counter vyskúšať (ToserticeMessenger.send (MSG);) Úlovok (REMOTEException e) (E.printstacktrace ();)) @override Public Void OnservisIdisconnected (Názov komponentov)))

Vysvetlím. Pri vytváraní ACTIVE, sme okamžite viazaní na službu, implementáciu servisného rozhrania a odosielame správu "Nastaviť servis počítadla", ktorá prejde nulou a vytváraním TosericEMessransher, prejdením rozhranie iBinder pre dizajnérovi. Mimochodom, v službe je potrebné vrátiť tento eHEMPLE, inak bude NPE. S touto triedou posielame správu služby. A tu je to mágia - uložíme našu inú inštanciu Messenger do variabilnej odpovede - ten, ktorý prijíma odpoveď zo servera a to je cez to, ktorá bude komunikovať s Active.

Ak chcete prijať správu zo služby, použite svoj obslužný program a hľadajte premenné, ktoré potrebujeme a urobíme akcie. Klikne na tlačidlá (CountInCrrcrick, CountDecrClick metódy), pošlite požiadavky na službu, pričom zadajte požadovanú akciu v msg.wat premennej.

Balenia com.example.servicetest; Import android.App.service; Import Android.content. *; Import Android.os. *; Import android.os.process; Import Android.util.log; Trieda verejnej triedy TestService rozširuje službu (verejná statická finálna finále Int_plus \u003d 1; verejný statical final int count_minus \u003d 2; verejný statical final int set_count \u003d 0; verejný statical finalt int get_count \u003d 3; int count \u003d 0; NESMIETERNÍCTOU ToActivityMessenger; @Override Public Void Oncreate () (super.oncreate (); HandlerThread Thread \u003d New HandlerThread ("ServiceStartarGuments", proces.Thread_priority_background); Thread.start (); Inclunler \u003d Nový NESPRÁVNY (Thread.getLooper ()); MesSanger \u003d Nový Messenger (Inclunler);) @override verejné ibinder onbind (návrat medsanger.getbinder ();) @override verejné zámery Onstartcommand (návrat štart_sticky;) // Správa Manipulácia AKTIVITY SÚKROMNÁ TRIEDA SÚKROMNÁ TRIEDA (Looper Looper) @Override Public Void HandleMessage (správa MSG) (//super.handleMessage(Msg); ToActivityMess enger \u003d msg.replyto; Prepínač (msg.what \u003d msg.arg1; log.d (mainActivity.Tag, "(Service) ... Nastaviť počet"); Break; Case Count_Plus: Count ++; Log.D (MACEACTIVITY.TAG, "(SERVIS ) ... Count Plus "); Break; Case Count_minus: Log.D (MACACTIVITY.TAG," (SERVICE) ... Počet mínus "); počet--; Break;) // Pošlite meračovú hodnotu Outmsg \u003d správa.obtain (inhander, get_count); outmsg.arg1 \u003d počet; outmsg.replyto \u003d mesranger; Skúste (ak (aktivitaMessenger! \u003d Null) toaktivityMessenger.send (outmsg);) úlovok (E.printstacctrace ();)))

All analógia s logikou v aktivovaní. Ani neviem, či potrebujete niečo vysvetliť. Jediným momentom je, že som okamžite odoslal žiadosť späť na aktiváciu v handleMessage, pomocou magických variabilných odpovedí a ťahaním vyššie uvedeného messengeru vyššie. A druhý moment, ktorý som už povedal, je:

@Override verejné ibder onbind (zámer arg0) (návrat medsanger.getbinder ();)

bez toho, čo všetko spadne. Toto je táto inštancia rozhrania, ktorá bude prenášaná na služby.

Záver

Všeobecne platí, že všetko. Takýto príklad interakcie Aktivity a služieb. Zdá sa mi, že non-triviálna interakcia je pekná, aj keď sa niekto môže zdať inak.

Otázky, objasnenia a iné v PM. Môžu existovať nepresnosť o akýchkoľvek aspektoch, takže neváhajte písať a narovnať.
Dúfam, že príspevok bol užitočný pre čitateľov.

Posledná aktualizácia: 04/03/2018

Pre prenos údajov medzi dvomi aktivitami sa používa zámerný objekt. Prostredníctvom svojej metódy publikácie () môžete pridať kľúč a súvisiacu hodnotu.

Napríklad, vysielanie zo súčasnej aktivity v druhej aktivite "Hello World" reťazce s kľúčom "Ahoj":

// Vytvorenie úmyselného objektu na spustenie Dodávky Intension Intens \u003d Nový zámer (tento, setupAktivita.class); // Prenos objektu s kľúčom "Hello" a "Hello World" Hodnota Intent.puppuxtra ("Ahoj", "Ahoj Svet"); // Začiatok štartktivity Nodávky (zámer);

Metóda Pulextra () sa používa na prenos dát, ktoré ako hodnota umožňuje preniesť najjednoduchšie typy typových dát - reťazec, Int, plavák, dvojlôžkové, dlhé, krátke, bajt, char, polia týchto typov, alebo Serializačný objekt rozhrania.

Ak chcete získať odoslané údaje pri načítaní nastavení, môžete použiť dostať.(), v ktorom sa objekt prenáša:

Bundle Arguments \u003d getintent (). GetExtras (); Názov string \u003d Arguments.Get ("Ahoj"). Tostring (); // Hello World.

V závislosti od typu dát odoslaných, pri prijatí, môžeme použiť niekoľko metód objektu zväzkov. Všetky z nich prijímajú objekt ako parameter. Hlavné sú:

    dostať (): univerzálna metódaktorá vráti hodnotu typu objektu. V súlade s tým sa pole o príjme musí byť prevedené na požadovaný typ

    getstring (): vráti reťazec typu objektu

    getint (): vráti hodnotu typu int

    getByte (): vráti hodnotu typu Byte

    getchar (): vráti hodnotu typu char

    getshort (): vráti hodnotu krátkeho typu

    getlong (): vráti dlhú hodnotu

    getfloat (): vráti hodnotu typu plavák

    getdouble (): vráti dvojitú hodnotu

    getBoolean (): Vracia hodnotu typu Boolean

    getMarRarray (): Vráti pole CHARP objektov

    getintarray (): vráti pole objektov INT

    getfloatarray (): vráti pole plavákových objektov

    getserializable (): Vracia objekt Serializable Interface

Dovoľte nám, aby sme v projekte definovali dve aktivity: MainActivity a druhá

V kóde o druhom čase určíme získanie údajov:

Balenie com.example.eugene.serializeApp; Import android.support.v7.Papp.AppCompaTActivity; Import android.os.bundle; Import Android.widget.TextView; Trieda verejnej triedy Rozšíri AppCompaTActivity (@override chránený Void Oncreate (Bundle SavedInstancestate) (Super.oncreate (SavedInstacestate); TextView TextView \u003d Nový textViete (this); TextView.settextSize (20); TextView.SetPadding (16, 16, 16, 16, 16 ); Bundle Arguments \u003d getintent (). GetExtras (); ak (argumenty! \u003d Null) (Názov string \u003d Argments.Get). TOSTRING (); String Company \u003d Arguments.getString ("Company"); Int Cena \u003d Argumenty. getint ("cena"); TextView.settext ("Názov:" + NAME + "NOCOMPANY:" + Company + "NPRICE:" + cena);) SETCONTENTVIEW (TEXTVIEW);)

V tomto prípade, v druhom prípade dostávame všetky údaje z objektu zväzku a zobrazí ich v textovom poli TextView. Predpokladá sa, že táto aktivita bude prenášaná tri prvky - dva riadky s názvom a firemnými kľúčmi a kľúčom s kľúčovou cenou.

Teraz budeme definovať prenos na druhú aktivitu údajov. Napríklad definujeme ďalšie rozhranie pre nedostatočnosť v súbore Activity_main.xml:

Páči sa vám článok? Zdieľaj to