Lietojumprogramma ne vienmēr sastāv no viena ekrāna. Piemēram, mēs esam izveidojuši ļoti noderīga programma un lietotājs vēlas zināt, kas ir autors. Viņš noklikšķina uz pogas “Par” un nonāk jaunā ekrānā, kurā ir noderīga informācija par programmas versiju, autoru, vietnes adresi, cik daudz kaķu ir autoram utt. Padomājiet par darbības ekrānu kā tīmekļa lapu ar saiti uz citu lapu. Ja paskatās uz kodu failā MainActivity.java no iepriekšējām nodarbībām jūs redzēsiet, ka mūsu klase Galvenā darbība attiecas arī uz Aktivitāte(vai viņa mantinieki) vai, pareizāk sakot, ir mantots no viņa.
Publiskā klase MainActivity paplašina AppCompatActivity
Kā jūs varētu nojaust, mums vajadzētu izveidot jaunu klasi, kas varētu izskatīties Galvenā darbība un pēc tam kaut kā pārslēdzieties uz to, noklikšķinot uz pogas.
Eksperimentam mēs ņemsim programmu no pirmās nodarbības un izmantosim pogu eksperimentiem (vai izveidosim jauns projekts ar vienu pogu uz ekrāna). Tālāk veidosim jauna forma parādīt noderīga informācija. Piemēram, parādīsim lietotājam, ko kaķis dara, kad tas iet pa kreisi un pa labi. Piekrītu, tas ir ļoti svarīga informācija, kas dod atslēgu Visuma atšķetināšanai.
Jaunu aktivitāti veidosim manuāli, lai gan studijai ir gatavas veidnes. Taču nav nekā sarežģīta un labākai izpratnei lietderīgi visu darīt ar rokām.
Izveidosim jaunu XML iezīmēšanas failu activity_about.xml mapē res / izkārtojums. Ar peles labo pogu noklikšķiniet uz mapes izkārtojumu un izvēlieties kādu no konteksta izvēlne Jauns | Izkārtojuma resursa fails. Parādīsies dialoglodziņš. Pirmajā laukā ievadiet faila nosaukumu aktivitāte_par. Otrajā ir jāievada saknes elements. Pēc noklusējuma tas ir tur Ierobežojuma izkārtojums. Izdzēsiet tekstu un ievadiet ritināšanas skats. Pietiek ar dažu rakstzīmju ievadīšanu, lai studija varētu ieteikt gatavas opcijas, jūs varat nekavējoties nospiest Enter, negaidot pilnu vārda ievadi:
Mēs iegūstam atbilstošo sagatavi, kurā ievietojam elementu teksta skats.
Informācija tiks izgūta no resursiem, proti, no virknes resursa par_tekstu. Tagad tas ir iezīmēts sarkanā krāsā, norādot uz informācijas trūkumu. varētu nospiest Alt+Enter un ievadiet tekstu dialoglodziņā. Bet mūsu piemērā šī metode nedarbosies, jo mūsu teksts būs vairāku rindiņu, izmantojot vadības rakstzīmes. Tāpēc darīsim savādāk. Atvērsim failu res/values/strings.xml un manuāli ievadiet šādu tekstu:
Mēs izmantojām vienkāršākos HTML teksta formatēšanas tagus, piemēram, , , . Mūsu piemēram, pietiek ar treknrakstu vārdus, kas attiecas uz kaķi un kustības virzienu. Lai tulkotu tekstu uz jauna līnija izmantot simbolus \n. Pievienosim vēl vienu virknes resursu jaunā ekrāna nosaukumam:
Saprotams ar uzcenojumu. Tālāk jums ir jāizveido loga klase AboutActivity.java. Izvēlieties no izvēlnes fails | Jauns | Java klase un aizpildiet nepieciešamos laukus. Sākumā pietiek norādīt tikai nosaukumu. Pēc tam nodarbojies ar citām jomām.
Sāksim sagatavošanos.
Tagad klase ir gandrīz tukša. Pievienosim kodu manuāli. Klasei ir jāmanto no abstraktās klases Aktivitāte vai tās radinieki FragmentActivity, AppCompatActivity utt. Pievienošana paplašina darbību. Darbības klasei ir jābūt metodei onCreate(). Novietojiet peles kursoru klasē un izvēlieties no izvēlnes kods | Ignorēt metodes(Ctrl+O). Dialoglodziņā mēs meklējam vajadzīgo klasi, uz tastatūras varat ierakstīt pirmās rakstzīmes Ātrā meklēšana. Izveidotajā metodē jums ir jāizsauc metode setContentView(), kas ekrānā ielādēs sagatavoto marķējumu. Mums būs tāda iespēja.
Package lv.alexanderklimov.helloworld; importēt android.app.Activity; importēt android.os.Bundle; /** * Izveidoja Aleksandrs Klimovs 12.01.2014. */ publiskā klase AboutActivity paplašina darbību ( @Override protected void onCreate(Bundle savedInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.activity_about); ) )
Tagad sākas vissvarīgākais. Mūsu uzdevums ir pāriet uz jaunu ekrānu, kad pirmajā ekrānā tiek noklikšķināts uz pogas. Atgriezīsimies klasē Galvenā darbība. Uzrakstīsim pogas klikšķu apstrādātāju:
Public Void onClick(Skatīt skats) ( Intent intent = new Intent(MainActivity.this, AboutActivity.class); startActivity(intent); )
Šeit es izmantoju nodarbībā aprakstīto pogu klikšķu apstrādes metodi.
Lai sāktu jaunu ekrānu, jums ir jāizveido klases gadījums Nolūks un norādiet pašreizējo klasi pirmajā parametrā un klasi pārejai otrajā, mums ir šis Par aktivitāti. Pēc tam metodi sauc startActivity(), kas palaiž jaunu ekrānu.
Ja tagad mēģināsit pārbaudīt lietojumprogrammu emulatorā, tiks parādīts kļūdas ziņojums. Ko mēs izdarījām nepareizi? Mēs nokavējām vienu svarīgu soli. Jums jāreģistrē jauns Aktivitāte manifestā AndroidManifest.xml. Atrodiet šo failu savā projektā un veiciet dubultklikšķi uz tā. Tiks atvērts faila rediģēšanas logs. Pievienojiet jaunu tagu
Šeit noder virknes resurss about_title. Palaidiet lietojumprogrammu, noklikšķiniet uz pogas un atveriet logu Par programmu. Tādējādi mēs uzzinājām, kā izveidot jaunu logu un izsaukt to, noklikšķinot uz pogas. Un mūsu rīcībā ir parādījusies mega ērta programma - tagad vienmēr būs pa rokai mājiens, ko kaķis dara, kad iet pa kreisi.
Vēlreiz vēršu uzmanību uz to, ka otrā izveidotā aktivitāšu klase ir jāmanto no klases Aktivitāte vai līdzīgi ( ListActivity utt.), jābūt XML iezīmēšanas failam (ja nepieciešams) un jābūt ierakstītam manifestā.
Pēc metodes izsaukšanas startActivity() sāksies jauna darbība (šajā gadījumā Par aktivitāti), tas kļūs redzams un tiks pārvietots uz skursteņa augšdaļu, kurā ir darbojošie komponenti. Izsaucot metodi pabeigt () no jaunās aktivitātes (vai nospiežot aparatūras atpakaļatkāpes taustiņu), tā tiks aizvērta un noņemta no steka. Izstrādātājs var arī pāriet uz iepriekšējo (vai jebkuru citu) darbību, izmantojot to pašu metodi startActivity().
Trešā ekrāna izveide - veids slinkiem
Programmētāji, tāpat kā kaķi, ir slinki radījumi. Vienmēr atcerieties, ka darbībai ir jāizveido marķējums un klase, kas tiek mantota Aktivitāte, un tad neaizmirsti reģistrēt klasi manifestā - ak nu, kas pie velna.
Šajā gadījumā izvēlieties no izvēlnes fails | Jauns | darbība | pamatdarbība(vai cits modelis). Pēc tam parādīsies pazīstamais logs jaunas aktivitātes izveidei. Aizpildiet obligātos laukus.
Noklikšķiniet uz pogas Pabeigt un darbība būs gatava. Lai to pārbaudītu, atveriet manifesta failu un pārbaudiet, vai nav jauna ieraksta. Es nerunāju par klases failiem un iezīmēm, tie parādīsies jūsu priekšā.
Pats galvenās aktivitātes ekrānā pievienojiet jaunu pogu un ierakstiet kodu, lai pārietu uz izveidoto aktivitāti.
Sākumā es ieteiktu manuāli izveidot visas nepieciešamās sastāvdaļas jaunai darbībai, lai saprastu attiecības starp klasi, marķējumu un manifestu. Un, kad jūs to pamanīsit, varat izmantot aktivitāšu izveides vedni, lai paātrinātu darbību.
Datu nodošana starp darbībām
Mēs izmantojām vienkāršāko piemēru, lai izsauktu citu darbību ekrānu. Dažreiz ir nepieciešams ne tikai izsaukt jaunu ekrānu, bet arī pārsūtīt datus uz to. Piemēram, lietotājvārds. Šajā gadījumā jums ir jāizmanto īpaša zona papildu dati, kas klasei ir Nolūks.
Novads papildu dati ir pāru saraksts atslēga/vērtība, kas tiek nodots kopā ar nolūku. Virknes tiek izmantotas kā atslēgas, un vērtībām varat izmantot jebkurus primitīvus datu tipus, primitīvu masīvus, klases objektus saišķis un utt.
Lai pārsūtītu datus citai darbībai, izmantojiet metodi liktExtra():
Intent.putExtra("Atslēga", "Vērtība");
Saņemšanas darbībai ir jāizsauc kāda piemērota metode: getIntExtra(), getStringExtra() utt.:
Int skaits = getIntent().getIntExtra("nosaukums", 0);
Pārveidosim iepriekšējo piemēru. Mums jau ir trīs aktivitātes. Pirmajai darbībai būs divi teksta lauki un poga. Izskats var būt šāds:
Otrajā aktivitātē Otrā aktivitāte iestatiet elementu teksta skats, kurā parādīsim no pirmās aktivitātes saņemto tekstu. Uzrakstīsim šādu metodes kodu onCreate() otrajā aktivitātē.
@Override protected void onCreate(Bundle savedInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); String user = "Dzīvnieks"; String gift = "donut hole"; TextView infoTextView = (TextView)Id(RBy) .id.textViewInfo); infoTextView.setText(lietotājs + " , jums tika dota " + dāvana); )
Ja mēs tagad palaižam programmu un vienkārši izsauksim otro logu, kā aprakstīts raksta pirmajā daļā, mēs redzēsim noklusējuma uzrakstu ZhYvotnoe, tev iedeva virtuļa caurumu. Piekrītu, ir diezgan žēl saņemt šādas ziņas.
Labojam situāciju. Pievienojiet kodu pirmajai darbībai:
Public Void onClick(View view) ( EditText userEditText = (ReditText) findViewById(R.id.editTextUser); EditText giftEditText = (ReditText) findViewById(R.id.editTextGift); Intent.intentMa =in IntentthintentMa =intent. klase); // ievietojiet tekstu no pirmā teksta lauka lietotājvārda atslēgā intent.putExtra("lietotājvārds", userEditText.getText().toString()); // nospiediet tekstu no otrā teksta lauka dāvanas atslēgā intent.putExtra("dāvana", dāvanaEditText.getText().toString()); startActivity(intent); )
Mēs ievietojām speciālā priekšmetu konteinerā Nolūks divas atslēgas ar vērtībām, kas ņemtas no teksta laukiem. Kad lietotājs ievadīs datus teksta laukos, tie nonāks šajā konteinerā un tiks nodoti otrajai darbībai.
Otrajai darbībai jābūt gatavai sirsnīgu ziņojumu saņemšanai, kā norādīts tālāk (izcelts treknrakstā).
// Noklusējuma vērtības String user = "LIFE"; Stīgu dāvana = "donut hole"; lietotājs = getIntent().getExtras().getString("lietotājvārds"); dāvana = getIntent().getExtras().getString("dāvana"); TextView infoTextView = (TextView)findViewById(R.id.textViewInfo); infoTextView.setText(lietotājs + " , jums tika dota " + dāvana);
Tagad ziņa nešķiet tik aizskaroša, bet dažiem pat patīkama. Sarežģītos piemēros datu apstrādes laikā ir vēlams pievienot validāciju. Pastāv situācijas, kad sākat otru darbību ar tukšiem datiem, piemēram, nulles, kas var avarēt lietojumprogrammu.
Mūsu gadījumā mēs zinām, ka mēs gaidām virknes vērtību, tāpēc kodu var pārrakstīt šādi:
nolūks nolūks = getIntent(); lietotājs = intent.getStringExtra("lietotājvārds");
Lietotājs = getIntent().getStringExtra("lietotājvārds");
Programmai ir trūkums – nav skaidrs, no kā saņemam sveicienus. Jebkurš labi audzināts pērtiķis nepieņems dāvanu no anonīma avota. Tāpēc mājasdarbam pievienojiet vēl vienu teksta lauku, lai ievadītu tā lietotāja vārdu, kurš sūta ziņojumu.
Google iesaka atslēgām izmantot šādu formātu: jūsu pakotnes nosaukums kā prefikss, kam seko pati atslēga. Šajā gadījumā jūs varat būt pārliecināti, ka atslēga ir unikāla, mijiedarbojoties ar citām lietojumprogrammām. Apmēram šādi:
Publiskā galīgā statiskā virkne LIETOTĀJS = "ru.alexanderklimov.myapp.USER";
Kas ierāmēja kaķi Vasku - rezultātu atgūstam
Ne vienmēr ir pietiekami vienkārši nodot datus citai darbībai. Dažreiz jums ir jāsaņem informācija no citas darbības, kad tā ir aizvērta. Ja pirms mēs izmantojām metodi startActivity (nolūka nolūks), tad ir saistīta metode startActivityForResult(Intent intent, int RequestCode). Atšķirība starp metodēm slēpjas papildu parametrā pieprasījuma kods. Tas būtībā ir tikai vesels skaitlis, ko varat iedomāties par sevi. Tas ir nepieciešams, lai atšķirtu, no kā iegūts rezultāts. Pieņemsim, ka jums ir pieci papildu ekrāni un jūs piešķirat tiem vērtības no 1 līdz 5, un no šī koda varat noteikt, kura rezultāts jums jāapstrādā. Varat izmantot vērtību -1, tad tā būs līdzvērtīga metodes izsaukšanai startActivity(), t.i. mēs nesasniegsim nekādu rezultātu.
Ja izmantojat metodi startActivityForResult(), tad jums ir jāignorē kodā norādītā metode, lai saņemtu rezultātu onActivityResult() un apstrādājiet rezultātu. Apjucis? Apskatīsim piemēru.
Pieņemsim, ka esat detektīvs. Saņemta informācija, ka restorānā no kādas ietekmīgas personas galda nozagti divi desas gabali un citi izstrādājumi. Aizdomas krita uz trim aizdomās turamajiem - vārnu, sasodītu suni un kaķi Vasku.
Viens no apmeklētājiem sniedza fotoattēlu sēriju no sava pontona iPhone:
Ir arī cita liecinieka liecība: Un Vaska klausās un ēd.
Veidojam jaunu projektu Šerloks ar divām aktivitātēm. Pirmajā ekrānā būs poga, lai pārslēgtos uz otro ekrānu, un teksta etiķete, kas parādīs zagļa vārdu.
Otrajā ekrānā būs radiopogu grupa:
Tā kā mēs gaidīsim atbildi no otrā ekrāna, mums ir jāizmanto šī metode startActivityForResult() pirmajā ekrānā, kurā mēs nodosim mainīgo IZVĒLIES_ZAGI kā parametrs pieprasījuma kods.
statiskā galīgā privātā int IZVĒLIES_ZAGI = 0; public void onClick(Skatīt v) ( Nolūka jautājumsIntent = jauns nolūks(Galvenā aktivitāte.this, ChooseActivity.class); startActivityForResult(jautājuma nolūks, IZVĒLĒTIES_ZAGI); )
Paskaties uz kodu. Kad tiek noklikšķināts uz pogas, mēs strādāsim ar otro ekrānu IzvēlietiesAktivitāte un palaidiet otro ekrānu, gaidot rezultātu.
Mēs pārejam uz otro ekrānu un mēs ierakstīsim otrās aktivitātes kodu.
Publisks galīgais statiskais String THIEF = "ru.alexanderklimov.sherlock.THIEF"; public void onRadioClick(View v) ( Intent answer Intent = new Intent(); switch (v.getId()) ( case R.id.radioDog: answerIntent.putExtra(THIEF, "Fucking Dog"); pārtraukums; gadījums R.id .radioCrow: answerIntent.putExtra(THIEF, "Crow"); break; case R.id.radioCat: answerIntent.putExtra(THHIEF, "Prževaļska zirgs"); pārtraukums; noklusējuma: pārtraukums; ) setResult(RESULT_OK, answer Intent); pabeigt ();)
Šeit viss ir vienkārši, kad detektīvs izvēlas noziedznieka vārdu, tad izmantojot metodi liktExtra() mēs nododam atslēgas nosaukumu un tās vērtību.
Ērtības labad pēc atlases mēs nekavējoties aizveram otro logu un pirms aizvēršanas nododam vērtību RESULT_OK lai būtu skaidrs, ka izvēle ir izdarīta. Ja lietotājs aizver ekrānu, izmantojot pogu Atpakaļ, vērtība tiks nodota RESULT_CANCELED.
Metode setResult()ņem divus parametrus: iegūto kodu un pašu rezultātu, kas attēlots kā nolūks. Iegūtais kods norāda, ar kādu rezultātu darbība beidzās, parasti tas ir vai nu Darbība.RESULT_OK, vai Darbība.RESULT_CANCELED. Dažos gadījumos jums ir jāizmanto savs atgriešanas kods, lai apstrādātu lietojumprogrammas opcijas. Metode setResult() atbalsta jebkuru veselu skaitļu vērtību.
Ja datus skaidri nosūtīsit caur pogu, būtu jauki pievienot metodi pabeigt () aizvērt otro darbību kā nevajadzīgu. Ja pāreja notiek, izmantojot pogu Atpakaļ, tas nav nepieciešams.
Ja darbību slēdza lietotājs, kad tika nospiesta aparatūras poga Atpakaļ, vai ja metode pabeigt () tika izsaukts pirms metodes setResult(), iegūtais kods tiks iestatīts uz RESULT_CANCELED un atgrieztais nolūks parādīs vērtību nulles.
Mēs atgriežamies pirmajā ekrānā. Pirmais ekrāns gaida atbildi no otrā ekrāna, tāpēc kodam jāpievieno metode onActivityResult().
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) ( super.onActivityResult(requestCode, resultCode, data); TextView infoTextView = (TextView) findViewById(R.id.textViewInfo); if (requestCode == CHOOSE_T if (resultCode == RESULT_OK) ( String thiefname = data.getStringExtra(ChooseActivity.THIEF); infoTextView.setText(thiefname); )else ( infoTextView.setText(""); // dzēst tekstu ) ) )
Metode sagaida ienākošos datus ar kodu IZVĒLIES_ZAGI, un, ja tiek saņemti šādi dati, tiek iegūta vērtība no atslēgas IzvēlietiesActivity.THIEF izmantojot metodi getStringExtra. Mēs izvadām iegūto vērtību uz teksta skats(mainīgs infoTextView). Ja mēs atgriezāmies ekrānā, izmantojot pogu Atpakaļ, mēs vienkārši izdzēšam tekstu.
Kad bērna darbība ir aizvērta vecākkomponentā, apdarinātājs tiek aktivizēts onActivityResult(). Apdarinātājs onActivityResult() aizņem vairākus parametrus.
- Pieprasījuma kods. Kods, ko izmanto, lai palaistu darbību, kas atgriež rezultātu
- Iegūtais kods. Rezultāta kods, ko iestatījis bērna darbība, kas norāda, kā bērna darbība beidzās. Tā var būt jebkura vesela skaitļa vērtība, bet parasti vai nu Darbība.RESULT_OK, vai Darbība.RESULT_CANCELED
- Dati. Atgriezto datu iesaiņošanas nolūks. Atkarībā no pakārtotās darbības mērķa tajā var būt ietverts URI ceļš, kas apzīmē atlasīto satura daļu. Alternatīvi (vai papildus) bērna darbība var atgriezt informāciju kā vienkāršas vērtības, kas ietītas nolūka parametrā ekstras
Ja bērna darbība beidzās negaidīti vai ja pirms tās aizvēršanas netika norādīts rezultāta kods, šis parametrs kļūs vienāds ar Darbība.RESULT_CANCELED.
Mēs sākam projektu, noklikšķiniet uz pogas un pārejam uz otro ekrānu. Tur mēs izvēlamies vienu no iespējām. Ja izvēlaties vārnu, ekrāns tiks aizvērts un pirmajā ekrānā tiks parādīts noziedznieka vārds. Ja izvēlaties suni, tiks parādīts viņa vārds.
Starp citu, ja atlasīsit kaķi, tā vārds netiks rādīts! Pārbaudiet un pārliecinieties paši. Jūs jautāsiet, kāpēc? Elementārais Vatsons! Pārkāpējs nav ņēmis vērā vienu svarīgu detaļu. Restorāns tika novērots no videokamerām, un ierakstā bija redzams, kurš patiesībā nozadzis desu un ierāmējis kaķi. Vaska, turies!
P.S. Ja sākumā kaut kas šķita nesaprotams, tad ar praksi daudz kas kļūs skaidrs. Datu pārsūtīšana starp ekrāniem ir izplatīta lietojumprogrammās, un jūs izpētīsit piemēru vairāk nekā vienu reizi.
P.P.S. Vislabākā zivs ir desa. Zinot šo vājumu, nebija grūti ierāmēt kaķi.
Izmantojot filtrus
Rakstā es parādīju izplatītu veidu, kā pārslēgties uz citu darbību, atrodoties metodē startActivity() ir norādīta pašreizējā klase un klase uz pāreju. Starp citu, aktivitāšu klasei nav jābūt daļai no jūsu pieteikuma. Ja zināt klases nosaukumu no citas lietojumprogrammas, varat arī pārslēgties uz to. Bet jūs varat pārslēgties uz citu darbību citādā veidā.
Praksē retāk sastopams, bet noderīgs. Pieņemsim, ka jums jau ir otra darbība. Manifestā pievienojiet tam īpašu filtru:
Un mēs palaižam otro darbību, noklikšķinot uz pogas šādā veidā.
Publisks void onClick(Skatīt skatu) ( startActivity(new Intent("ru.alexanderklimov.testapplication.SecondActivity"); )
Aizstāsim garu virkni ar konstanti.
Public static final String ACTION_SECOND_ACTIVITY = "ru.alexanderklimov.testapplication.SecondActivity"; public void onClick(Skatīt skatu) ( startActivity(new Intent(ACTION_SECOND_ACTIVITY)); )
Tātad, ko mēs esam izdarījuši. Otrajai darbībai esam reģistrējuši filtru un norādījuši nosaukumu darbība atribūtā android:nosaukums. Ērtības labad es vienkārši ievietoju tajā pilnu aktivitātes nosaukumu ar iepakojuma nosaukumu. Klases konstruktors Nolūks ir vairākas pārslogotas versijas. Vienā versijā varat norādīt darbības virkni. Norādījām savu izveidoto akciju, kas ir reģistrēta otrajā aktivitātē. Sistēma darbības laikā aplūko visu instalēto lietojumprogrammu manifestus. Meklējot atbilstību, sistēma atrod mūsu filtru un palaiž vēlamo darbību.
Pēc tāda paša principa jūs varat sākt citas darbības. Apskatiet piemēru. Ja kopējat piemēru pie sevis un apskatāt dokumentāciju par android.provider.Settings.ACTION_AIRPLLANE_MODE_SETTINGS, jūs redzēsiet, ka šis kods atbilst virknes konstantei public static final java.lang.String ACTION_AIRPLANE_MODE_SETTINGS = "android.settings.AIRPLANE_MODE_SETTINGS". Salīdziniet ar mūsu kodu. Varat pieņemt, ka bezsaistes režīma iestatījumu darbības filtrā ir šī rinda.
Filtra kategorijas nosaukums android.intent.category.DEFAULT liek sistēmai veikt noklusējuma darbību, proti, sākt darbību. Ir arī citi vārdi, kas mūs pagaidām neinteresē.
Un tagad grūts jautājums. Kas notiek, ja izveidojat citu darbību un norādāt to pašu filtru kā otrajai darbībai? Un pārbaudīsim. Izveidojiet sev trešo aktivitāti un kopējiet tajā bloku ar filtru no otrās aktivitātes.
Mēs noklikšķinām uz pogas pirmajā darbībā. Sistēma lūgs jums izvēlēties vajadzīgo opciju.
Ja izvēlaties vienumu VIENMĒR tad nākamreiz jums nebūs jāizvēlas. Lai atiestatītu atlasi, sadaļā Iestatījumi atveriet lietojumprogrammas rekvizītus un atrodiet pogu notīrīt noklusējuma iestatījumus.
Aktivitātes uzsākšana pēc tās nosaukuma
Konstruktorā Nolūks Otrais parametrs ir klase. Bet pieņemsim, ka ir kaut kāda datu bāze, kurā ir norādīti aktivitāšu nosaukumi un ir jāpalaiž vēlamā darbība pēc tās nosaukuma. Mēs varam iegūt pašu klasi, pamatojoties uz virknes mainīgo, un sākt darbību.
Mēģiniet ( // Aktivitātes klases pilns nosaukums String activityName = "ru.alexanderklimov.testapplication.SecondActivity"; // iegūt klases klases objektu>myClass = Class.forName(aktivitātesNosaukums); Intent intent = new Intent(this, myClass); startActivity(nodoms); ) noķert (ClassNotFoundException e) ( e.printStackTrace(); )
Kaut kā man bija uzdevums pārsūtīt datus no pakalpojuma uz darbību. Sākās risinājuma meklēšana standarta SDK, bet tā kā nebija laika, tad pieņēmu sliktu lēmumu datu bāzes izmantošanas veidā. Bet jautājums bija atklāts un pēc kāda laika es izdomāju pareizāku veidu, kas ir SDK - izmantojot Message, Handler, Messenger klases.
Ideja
Mums ir jāpārsūta dati no darbības uz pakalpojumu un otrādi. Kā mēs to varam izdarīt? Lai atrisinātu mūsu problēmu, mums jau ir viss nepieciešamais. Viss, kas nepieciešams, ir saistīt pakalpojumu ar darbību, izmantojot bindService, nodot nepieciešamos parametrus un nedaudz maģijas, izmantojot Message klases. Un burvība ir izmantot Message instances mainīgos un jo īpaši replyTo. Šis mainīgais ir nepieciešams, lai mēs varētu piekļūt pakalpojuma Messenger gadījumam no darbības un pakalpojumā līdz aktivitātes Messenger instancei. Patiesībā tas nav tik vienkārši. Vismaz manam ne pārāk apdāvinātajam prātam. Daļēji es tikai uzlaboju jau esošo dokumentāciju — Pakalpojumi Turklāt ir labs StackOverflow piemērs. Katrā ziņā ceru, ka raksts vismaz kādam noderēs un nestrādāju velti.
Piemērs
Piemēram, mēs ieviesīsim pakalpojumu, kas palielinās un samazina skaitītāja vērtību un atgriezīs rezultātu aktivitātē TextView. Izkārtojuma kodu izlaidīšu, jo ir divas pogas un teksta lauks - viss ir vienkārši.
Īstenošana
Šeit ir pilns aktivizācijas kods:
Publiskā klase MainActivity paplašina darbību (publisks statisks galīgais String TAG = "TestService"; TestServiceConnection testServConn; TextView testTxt; galīgais ziņnesis sūtnis= new Messenger(new IncomingHandler()); Messenger toServiceMessenger; @Override public void onCreate(Bundle savedInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); testTxt = (TextView)findViewById(R.id.test_txt); bindService(new Intenter(vicethis) ), (testServConn = jauns TestServiceConnection()), Context.BIND_AUTO_CREATE); ) @Ignorēt publisko void onDestroy()( super.onDestroy(); unbindService(testServConn); ) public void countIncrClick(View button) = Message.msg iegūt(null, TestService.COUNT_PLUS); msg.replyTo = messenger; try ( toServiceMessenger.send(msg); ) catch (RemoteException e) ( e.printStackTrace(); ) ) public void countDecrClick(View button)( Message msg = Message.obtain(null, TestService.COUNT_MINUS); msg.replyTo = messenger; try ( toServiceMessenger.send(msg); ) catch (RemoteException e) ( e.printStackTrace(); ) ) privātā klase IncomingHandler paplašina apdarinātāju ( @Override public void handleMessage(Message msg)( switch (msg.what) ( case TestServic e.GET_COUNT: Log.d(TAG, "(activity)...get count"); testTxt.setText(""+msg.arg1); pārtraukums; ) ) ) privātā klase TestServiceConnection ievieš ServiceConnection ( @Override public void onServiceConnected(ComponentName nosaukums, IBinder pakalpojums) ( toServiceMessenger = new Messenger(service); //nosūtīt sākotnējā vērtība skaitītājs Message msg = Message.obtain(null, TestService.SET_COUNT); msg.replyTo = kurjers; msg.arg1 = 0; //mūsu counter try ( toServiceMessenger.send(msg); ) catch (RemoteException e) ( e.printStackTrace(); ) ) @Override public void onServiceDisconnected(ComponentName name) ( ) ) )
Ļauj man paskaidrot. Veidojot aktivitāti, mēs nekavējoties saistāmies ar pakalpojumu, ieviešot ServiceConnection interfeisu un nosūtām servisam ziņojumu “iestatiet skaitītāja vērtību” tajā, nododot nulli un izveidojot toServiceMessanger, nododot IBinder interfeisu konstruktoram. Starp citu, šis gadījums ir jāatgriež pakalpojumā, pretējā gadījumā būs NPE. Ar šīs klases palīdzību mēs nosūtām ziņojumus dienestam. Un šeit tā ir maģija - mainīgajā replyTo mēs saglabājam savu otru Messenger instanci - to, kas saņem atbildi no servera, un caur to tiks veikta saziņa ar darbību.
Lai saņemtu ziņojumu no pakalpojuma, mēs izmantojam mūsu apdarinātāju un vienkārši meklējam vajadzīgos mainīgos un veicam darbības ar tiem. Uz pogas klikšķiem (metodes countIncrClick, countDecrClick) mēs nosūtām servisam pieprasījumus, mainīgajā msg.what norādot vēlamo darbību.
Package com.example.servicetest; importēt android.app.Service; importēt android.content.*; importēt android.os.*; importēt android.os.Process; importēt android.util.Log; public class TestService paplašina pakalpojumu (publisks statiskais galīgais int COUNT_PLUS = 1; publiskais statiskais galīgais int COUNT_MINUS = 2; publiskais statiskais galīgais int SET_COUNT = 0; publiskais statiskais galīgais int GET_COUNT = 3; int count = 0; IncomingHandler inHandler; Messenger Messenger; Messenger toActivityMessenger; @Override public void onCreate()( super.onCreate(); HandlerThread pavediens = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); inHandler = new IncomingHandler(thread).megetssaLooper(pavediens). = new Messenger(inHandler); ) @Override public IBinder onBind(Intent arg0) (atgriež messsanger.getBinder(); ) @Override public int onStartCommand(Intent intent, int karogi, int startId) (atgriešanās START_STICKY; ) //message apdarinātājs aktivitātes privātā klase IncomingHandler paplašina apdarinātāju ( public IncomingHandler(Looper looper)( super(looper); ) @Override public void handleMessage(Message msg)( //super.handleMessage(msg); toActivityMess enger = msg.replyTo; slēdzis (msg.what) ( case SET_COUNT: count = msg.arg1; Log.d(MainActivity.TAG, "(service)...set count"); break; case COUNT_PLUS: count++; Log.d(MainActivity.TAG , "(service)...count plus"); break; case COUNT_MINUS: Log.d(MainActivity.TAG, "(service)...count minus"); count--; break; ) //skaitītāja nosūtīšana vērtība aktivitātē Message outMsg = Message.obtain(inHandler, GET_COUNT); outMsg.arg1 = skaits; outMsg.replyTo = ziņojumapmaiņa; mēģināt ( if(toActivityMessenger != null) toActivityMessenger.send(outMsg); ) noķert (RemoteException e) ( e.printStackTrace(); ) ) ) )
Viss pēc analoģijas ar darbības loģiku. Es pat nezinu, vai man kaut kas jāpaskaidro. Vienīgais jautājums ir tāds, ka es nekavējoties nosūtu pieprasījumu atpakaļ uz handMessage darbību, šim nolūkam izmantojot mainīgo magic replyTo un izvelkot vēlamo Messenger iepriekš. Un otrs punkts, ko es jau minēju, ir:
@Ignorēt publisko IBinder onBind(Intent arg0) (atgriezt messsanger.getBinder(); )
bez kura viss izkritīs. Šī saskarnes instance tiks nodota pakalpojumam ServiceConnection
Secinājums
Visā visumā. Šāds izdomāts darbības un pakalpojuma mijiedarbības piemērs. Man šķiet, ka tā ir diezgan netriviāla mijiedarbība, lai gan kādam tā var šķist savādāka.
Jautājumi, precizējumi utt. Var būt neprecizitātes par jebkuriem aspektiem, tāpēc droši rakstiet un labojiet.
Es ceru, ka raksts bija noderīgs lasītājiem.
Sveiki.
Caur UART saņemtos datus nepieciešams pārsūtīt uz Aktivitāti. To var izdarīt, aktivitātē izveidojot pavedienu, kurā sakārtot (!isInterrupted()) cilpu un nolasīt datus no UART bufera. Pēc tam, izsaucot Aktivitātes UI pavedienu - MainActivity.this.runOnUiThread(new Runnable() , veiciet nepieciešamās darbības ar šo Aktivitāti. Bet, ja izsaucam citas Aktivitātes no galvenās aktivitātes, tad sakārtotais pavediens neļauj iziet datus uz jaunizveidotajām Aktivitātēm.Ja pareizi saprotu, lai dati no straumes tiktu pārsūtīti uz kādu Aktivitāti, straume jāveido nevis Aktivitātē, bet Pakalpojumā.
Jautājums: dati nāca caur UART, pavedienā (kas ir izveidots Servce) ir nepieciešams pārsūtīt datus uz Activity, kas tagad ir aktīva, kā to var izdarīt un vai tas vispār tiek darīts?
1 atbilde
Katrā darbībā izveidojiet apdarinātāju. Šīs aktivitātes metodē onResume() tiek veikta bindService(). Tur viens no parametriem ir saskarne ServiceConnection. Ieviesiet to ar vismaz tādu pašu aktivitāti. Ieviesiet tajā metodi onServiceConnected(). Šajā atzvanīšanā pats pakalpojums ir viens no parametriem. Tāpēc sauciet šo pakalpojumu par savu setHandler() metodi. Nododiet tur apdarinātāju, kas atrodas pašreizējā darbībā. Bet iemet ienākošos datus, izmantojot UART, šī apdarinātāja pakalpojumā. Starp citu, Handler tradicionāli darbojas galvenajā pavedienā, tāpēc nebūs nepieciešams palaist runOnUiThread .