Contacte

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:

Ți-a plăcut articolul? Împărtășește-l