Програм Андроид: Процеси, нити и услуге

У овом водичу ћемо објаснити како Андроид делује при покретању услуге, описаћемо од чега се састоје нити извођења и о каквим се процесима ради. То ће нам омогућити да разумемо начин рада наших апликација, дајући нам већу контролу и стабилност на мобилним уређајима на којима ће бити инсталирани.

Тхреад


Када корисник покрене апликацију, Андроид ствара нит која се зове маин (маин). Ова нит је веома важна јер је задужена за управљање догађајима које корисник покреће у одговарајућим компонентама и такође укључује догађаје који исцртавају екран. Нит извршења, најмањи део који може да обради планер у оперативном систему, у овом случају Андроид (са Линук језгром).

Тхе имплементација више нити који се истовремено обрађују у истој апликацији, (назовите то истовременост, што се односи на истовременост извршења), позната је као вишенавојна. Мултитхреадинг се примењује тако да ове нити деле ресурсе И ово је оно што процес обухвата, запамтите да се то може програмски применити у коду исте апликације, имплементација вишеструког низирања на нивоу оперативног система не зависи од нас.

Почетак животног циклуса апликације укључује генерисање новог процеса Линука којем је додељена Главна нит или УИ нит (нит која је одговорна за графичку обраду апликације, нит корисничког интерфејса на енглеском).

БелешкаЖивотни циклус укључује извршавање метода: онЦреате (), онСтарт () и онРесуме (); на свом почетку и при његовом затварању: онПаусе (), онСтоп () и онДестрои ().

Андроид може присилити процес да се затвори због недостатка меморије. Ова врста случаја је ретка због технолошког напретка, али се и даље дешава.

Питање је: Које процесе Андроид одлучује да затвори?

Они се затварају упоређивањем њиховог нивоа важности, сажето је како следи:

Најважнији: процеси у првом плануКорисник је у интеракцији са наведеним процесом (метода онРесуме () тог процеса је тренутно покренута). Постоји услуга која користи методе свог животног циклуса. Или постоји а БроадцастРецеивер трчање његово метода онРецеиве ().

Други најважнији: Видљиви процесиАктивност са позивом на онПаусе () метод. Услуга повезана са видљивом активношћу (везана услуга).

Трећи најважнији: Процес са услугомКорисник нема директну интеракцију са процесом. Процес има услугу која ради у позадини.

Друго најмање важно: Позадински процесНе постоји врста интеракције са корисником. Процес који је корисник последњи пут погледао биће последњи који ће бити уништен.

Најмање важно: Празан процесНема активних компоненти. Процес је још увек жив у сврху кеширања, спречавајући корисника да се врати на употребу тог процеса.

Овај други, празан процес, први се прекида у случају недостатка меморије. Тако ће апликација која имплементира услугу у којој се ствара нит за преузимање садржаја са Интернета бити важнија од апликације која ствара нит без имплементације услуге, тако да је већа вероватноћа да ће бити прекинута пре довршетка преузимања. , јер су то дуготрајни процеси.

Да бисте разумели мултиреадинг да видимо како Андроид управља својом главном нитом.

ПРОЦЕС А има кориснички интерфејс или ГЛАВНА нит, ова нит обрађује а ред порука или ред порука, који се покреће док нит постаје неактивна, ко то решава? Тхе Лоопер.

Лоопер је класа корисничког интерфејса Андроид Јава да, заједно са Хандлер цласс, обрађује догађаје корисничког интерфејса, попут притиска на тастере, прецртаних екрана и прекидача за оријентацију. Догађаји се такође могу користити за учитавање садржаја у ХТТП услугу, промену величине слика и извршавање удаљених захтева. Кључна карактеристика ових класа је то што су у стању да имплементирају образац истовремености.

Тхе Андроид Лоопер класа садржи а МессагеКуеуе (ред порука) и повезан је само са темом из које је креиран. Имајте на уму да се ова веза не може прекинути и да лЛоопер не може се повезати са било којом другом нити. Такође, Лоопер је на локалној меморији и може се позвати само са статичке методе. Метода постављања проверава да ли је Лоопер већ повезан са нити, а затим статичка метода креира Лоопер. Након тога, петља се може користити за проверу порука у реду.

До сада смо разумели неколико концепата: процес, нит, нит корисничког интерфејса, петља, али још увек не знамо зашто вишеструкост.

Дуготрајно пословање


Сматра се дугим за сваку методу чије извршавање прелази 5 секунди, што покреће типичну поруку „апликација не реагује. Да ли желите да га затворите?

Шта могу бити ове операције?: Приступ Интернету, СКЛ упити, КСМЛ / ХТМЛ / ЈСОН рашчлањивање, сложена графичка обрада. Било која од ових операција које се изводе у главној нити ће је блокирати, а будући да она управља графичким корисничким интерфејсом, тумачи се као замрзавање, које андроид одлучује да затвори.

Замислимо само да било која од ових операција траје 7 секунди и корисник одлучи да напише нешто у неки начин уноса текста, па иако ових 7 секунди није протекло, нит корисничког интерфејса не може ажурирати приказ тако да корисник цени да пише, и тако да генерише замрзавање, покреће се порука "без одговора" са којом имате две опције, сачекајте или уништите, иако никада не можете знати колико дуго чекати, то може бити неколико секунди или чак минута у зависности од реда порука који имају главну нит.

Како да избегнемо смрзавање?


Коришћење нити или услуга, у зависности од тога да ли задатак захтева измену приказа, у овом случају је услуга имплементирана јер се приказ апликације не може мењати изван нити корисничког интерфејса. Најбољи начин да избегнете замрзавање је коришћење Асинхроних задатака са класом АсинцТаск, у овом водичу ћемо имплементирати више нити да бисмо разумели понашање Андроид архитектуре.

Код и развој


Пројекат који ћемо следеће створити ће се заснивати на преузимању слике помоћу које морамо створити нит која нам омогућава управљање приступом и преузимањем путем интернета јер ГЛАВНИ или УИ Тхреад не дозвољава ову радњу.

Почећемо стварањем новог пројекта са празном активношћу, назвали смо овај пројекат "МултиТхреадЕкампле", са једном једноставном активношћу креираћемо структуру КСМЛ датотеке која припада овој делатности.

 
Имамо текстуално поље, дугме, линеарни распоред који одговара неодређеној траци за учитавање које ћемо касније користити и приказ листе који садржи низ УРЛ адреса слика хостованих на интернету. У датотеци која садржи класу Јава за нашу (јединствену) активност написана је следећим кодом:
 пакет цом.омглабс.мултитхреаекампле; импорт андроид.суппорт.в7.апп.АппЦомпатАцтивити; импорт андроид.ос.Бундле; импорт андроид.виев.Виев; увоз андроид.видгет.АдаптерВиев; импорт андроид.видгет.ЕдитТект; импорт андроид.видгет.ЛинеарЛаиоут; увоз андроид.видгет.ЛистВиев; увоз андроид.видгет.ПрогрессБар; јавна класа МаинАцтивити проширује АппЦомпатАцтивити имплементира АдаптерВиев.ОнИтемЦлицкЛистенер {привате ЕдитТект едитТект; приватни ЛистВиев листВиев; привате Стринг [] урл; приватни ПрогрессБар прогрессБар; приватни ЛинеарЛаиоут прогрессЛаиоут; @Оверриде протецтед воид онЦреате (Бундле саведИнстанцеСтате) {супер.онЦреате (саведИнстанцеСтате); сетЦонтентВиев (Р.лаиоут.ацтивити_маин); едитТект = (ЕдитТект) финдВиевБиИд (Р.ид.довнлоадУРЛ); листВиев = (ЛистВиев) финдВиевБиИд (Р.ид.листурлс); листВиев.сетОнИтемЦлицкЛистенер (ово); урлс = гетРесоурцес (). гетСтрингАрраи (Р.арраи.УРЛс); прогрессБар = (ПрогрессБар) финдВиевБиИд (Р.ид.прогрессбар); прогрессЛаиоут = (ЛинеарЛаиоут) финдВиевБиИд (Р.ид.прогресслаиоут); } публиц воид довнлоад (Виев виев) {} @Оверриде публиц воид онИтемЦлицк (АдаптерВиев адаптерВиев, Виев виев, инт и, лонг л) {едитТект.сетТект (урл [и]); }} 
До сада се апликација могла саставити без икаквих проблема, у овој класи декларирамо варијабле:
  • едитТект
  • листВиев
  • урл
  • прогрес бар
  • прогрессЛаиоут

Текстуално поље, листа, распоред низа, трака напретка и линеарни распоред.

У онЦреате метод Њима додељујемо одговарајући приказ који им припада и који су створени у КСМЛ датотеци активности, са изузетком УРЛ -ова који додељују своје вредности из фасцикле вредности у датотеци стринга и чији је распоред декларисан као што следи:

 хттп://ввв.фмдос.цл/вп-цонтент/уплоадс/2016/03/1.јпг хттп://вигнетте3.викиа.ноцоокие.нет/теенволф/имагес/9/90/Цристал_Реед_003.јпег хттпс: // пбс.твимг.цом/профиле_имагес/699667844129107968/ЕвхТФБХН.јпг хттп://вигнетте1.викиа.ноцоокие.нет/теен-волф-пацк/имагес/0/0б/Холланд-холланд-роден-31699868-500-600.пнг 
Празан начин преузимања (приказ Виев) биће испуњен кодом који ће извршити преузимање и који је повезан са Дугме за преузимање Бот преко атрибута онцлицк. Коначно онитемцлицк методом који припада листвиев, испуњава текстуално поље када кликнете на било који урл који се налази на листи. Након састављања овај код ће изгледати овако:

У следећем кораку ћемо креирати методе које ће прећи на преузимање, пратећи ове кораке:

  • Направите објекат класе УРЛ -а (јава.нет) који ће представљати урл за преузимање.
  • Отворите везу помоћу тог објекта.
  • Читајте податке (путем веба) користећи класу улазног тока у низу бајтова.
  • Отворите / креирајте датотеку излазног тока у којој ће се урл подаци сачувати на СД картици.
  • Упишите податке у ту датотеку.
  • И на крају затворите везу.

За сада ће то изгледати овако:

 јавно логичко преузимање помоћуТхреадс (веза низа) {боолеан цонфирматион = фалсе; УРЛ довнлоадЛинк = нулл; ХттпУРЛЦоннецтион цонне = нулл; ИнпутСтреам инпутСтреам = нулл; пробајте {довнлоадЛинк = нови УРЛ (веза); цоннецтион = (ХттпУРЛЦоннецтион) довнлоадЛинк.опенЦоннецтион (); инпутСтреам = цонне.гетИнпутСтреам (); } цатцх (МалформедУРЛЕкцептион е) {е.принтСтацкТраце (); } цатцх (ИОЕкцептион е) {е.принтСтацкТраце (); } коначно {иф (цоннек! = нулл) {цоннек.дисцоннецт (); } иф (инпутСтреам! = нулл) {пробај {инпутСтреам.цлосе (); } цатцх (ИОЕкцептион е) {е.принтСтацкТраце (); }}} потврда о повратку; } 
Ова метода коју смо изградили требаће само Низ који ће бити УРЛ за преузимање, је боолеан Да бисте потврдили преузимање, довнлоадЛинк је УРЛ објекат, веза је веза која ће бити успостављена за приступ објекту, а инпутСтреам је она која ће наставити са читањем података, ако покушамо да користимо овај метод на дугмету довнлоадБот апликација би се зауставила због немогућности покретања на главна нит.

Овде идемо са коришћењем нити, постоје два начина да се то уради са класом, а то је проширивањем те класе на Тхреад или имплементацијом класе Руннабле, ова класа није нит која вам једноставно омогућава да креирате метод који ћете може покренути у одређеном тренутку и ако креирате засебну нит, покрените је у њој.

Унутар дугмета за преузимање написаћемо овај код који ће изгледати овако:

 публиц воид довнлоад (Виев виев) {Тхреад мТхреад = нова тема (нова мРунн ()); мТхреад.старт (); } 
Овде стварамо нову нит којој је потребан Руннабле објекат који креирамо у приватној класи попут ове:
 приватна класа мРунн имплементира Руннабле {@Оверриде публиц воид рун () {довнлоад усингТхреадс (урлс [0]); }} 
Направите приватну класу

БелешкаУпамтите да је ово све у класи Јава наше једине активности.

Са линијом:

 преузимање помоћуТреадс (урл [0]);
Позивамо функцију коју смо креирали тамо где смо отворили везу, ставка УРЛ низа јој се прослеђује како би могла да чита податке са те адресе. Касније ће бити измењен.

Ако бисмо покушали покренути ову апликацију притиском на дугме, апликација би се зауставила, јер нам је потребна посебна дозвола за приступ интернету, која се тражи кроз манифест наше апликације. Додавање реда испред ознаке:

 
Сада ћемо потврдити да апликација заиста преузима додаћемо неколико редова кода у метод преузимања усингТхреадс, то ће изгледати овако:
 јавно логичко преузимање помоћуТхреадс (веза низа) {боолеан цонфирматион = фалсе; УРЛ довнлоадЛинк = нулл; ХттпУРЛЦоннецтион цонне = нулл; ИнпутСтреам инпутСтреам = нулл; ФилеОутпутСтреам арцхОутпутСтреам = нулл; Датотека датотека = нулл; пробајте {довнлоадЛинк = нови УРЛ (веза); цоннецтион = (ХттпУРЛЦоннецтион) довнлоадЛинк.опенЦоннецтион (); инпутСтреам = цонне.гетИнпутСтреам (); датотека = нова датотека (Енвиронмент.гетЕктерналСторагеПублицДирецтори (Енвиронмент.ДИРЕЦТОРИ_ДОВНЛОАДС) + "/" + Ури.парсе (веза) .гетЛастПатхСегмент ()); арцхОутпутСтреам = нови ФилеОутпутСтреам (датотека); инт Читање = -1; бајт [] бафер = нови бајт [1024]; вхиле ((Читање = инпутСтреам.реад (бафер))! = -1) {арцхОутпутСтреам.врите (бафер, 0, читање); } потврда = тачно; } цатцх (МалформедУРЛЕкцептион е) {е.принтСтацкТраце (); } цатцх (ИОЕкцептион е) {е.принтСтацкТраце (); } коначно {иф (цоннек! = нулл) {цоннек.дисцоннецт (); } иф (инпутСтреам! = нулл) {пробај {инпутСтреам.цлосе (); } цатцх (ИОЕкцептион е) {е.принтСтацкТраце (); }} иф (арцхОутпутСтреам! = нулл) {три {арцхОутпутСтреам.цлосе (); } цатцх (ИОЕкцептион е) {е.принтСтацкТраце (); }}} потврда о повратку; } ФилеОутпутСтреам арцхОутпутСтреам = нулл; Датотека датотека = нулл; 
Декларације ових објеката представљају писање датотеке која се чита и празну датотеку у коју ће се читање сачувати.
 датотека = нова датотека (Енвиронмент.гетЕктерналСторагеПублицДирецтори (Енвиронмент.ДИРЕЦТОРИ_ДОВНЛОАДС) + "/" + Ури.парсе (урлс [0]). гетЛастПатхСегмент ()); арцхОутпутСтреам = нови ФилеОутпутСтреам (датотека); инт Читање = -1; бајт [] бафер = нови бајт [1024]; вхиле ((Читање = инпутСтреам.реад (бафер))! = -1) {арцхОутпутСтреам.врите (бафер, 0, читање); } потврда = тачно; 
„Датотека“ је празан објекат Датотека чија је адреса направљена приступом СД картици „Енвиронмент.гетЕктерналСторагеПублицДирецтори (Енвиронмент.ДИРЕЦТОРИ_ДОВНЛОАДС)“ и додавањем косе црте „/“ и последњег сегмента УРЛ -а који генерално представља назив датотеке у преузимањем, то постижемо методом гетЛастПатхСегмент ().

Пре тестирања апликације додаћемо последњу дозволу у манифест:

 
Након покретања апликације на емулатору или Андроид уређају, притиском на дугме видећемо да се очигледно ништа не дешава, али ако проверимо фасциклу Преузми помоћу истраживача датотека, схватићемо да је прва ставка на листи преузета; фотографија која се зове 1.јпг.

Урадити то динамичку апликацију и имплементирати УРЛ адресе приказа листе, ажурираћемо начин преузимања (приказ) и додаћемо ово, као први ред:

 Стринг линк = едитТект.гетТект (). ТоСтринг ();
И у мРунн цласс додаћемо ово, пре методе рун ():
 приватна класа мРунн имплементира Руннабле {привате Стринг линк; публиц мРунн (Веза низа) {тхис.линк = веза; } @Оверриде публиц воид рун () {довнлоад усингТхреадс (линк); }}
И у мРунн цласс додаћемо ово, пре методе рун ():

Тако можемо променити променљиву везе из поља за текст у методу која врши преузимање. Апликација је у овом тренутку потпуно функционална, иако јој недостаје мало прилагођености корисницима, па ћемо покушати то поправити, користећи траку напретка коју смо навели на почетку.

У класу мРунн у методу рун () ћемо укључити:

 МаинАцтивити.тхис.рунОнУиТхреад (нев Руннабле () {@Оверриде публиц воид рун () {прогрессЛаиоут.сетВисибилити (Виев.ВИСИБЛЕ);}}); 
Пре позива на довнлоадусандоТхреадс. Ово ће учинити да се трака за учитавање појави када притиснемо дугме, у коначној клаузули метод преузимања усингТхреадс.

Додаћемо:

 тхис.рунОнУиТхреад (нев Руннабле () {@Оверриде публиц воид рун () {прогрессЛаиоут.сетВисибилити (Виев.ГОНЕ);}}); 
Дакле, када се преузимање заврши, трака поново нестаје. То ће се догодити без обзира на то да ли је преузимање успешно.
И ово је било све, једно кратка имплементација више нитиОво је помало досадно и доноси неке компликације за сложеније апликације.Најефикаснији начин за постизање овог задатка, у нашем случају преузимање неких слика, је коришћење АсинцТаскс.

wave wave wave wave wave