Kuvien käsittely on usein muistia kuluttavaa, ja tämä saattaa johtaa "Out of Memory" (OOM) -virheisiin, erityisesti silloin, kun työskennellään suurten kuvien kanssa. Tämä ongelma on erityisen yleinen, kun käytetään kameralla otettuja kuvia, jotka saattavat olla laajakokoisia ja paljon laitteiden itse tukemia suurempia. Vaikka suuret kuvat eivät aina tuota näkyvää etua sovelluksen käyttöliittymässä, niiden täysikokoisena lataaminen voi olla tarpeetonta ja muistirajoitteiden takia jopa haitallista. Tässä käsitellään tapoja, joilla voidaan pienentää kuvia, jotta vältetään muistivirheitä ja parannetaan sovelluksen suorituskykyä.

Ensimmäinen askel suurempien kuvien käsittelyssä on niiden skaalaminen. Kuvan skaalaaminen ei tarkoita sen yksinkertaista pienentämistä vaan eräänlaista kuvan näytettävän osan valitsemista siten, että se vastaa tarkalleen laitteen näyttöön tarpeellista kokoa. Tämä säästää huomattavasti muistia ja parantaa sovelluksen suorituskykyä.

Kun työskennellään kuvien kanssa, erityisesti suurten kuvien, joita ei ole tarpeen ladata täysikokoisina, kannattaa hyödyntää Androidin tarjoamia työkaluja kuten BitmapFactory ja sen inSampleSize -asetusta. Tämä mahdollistaa kuvan koon pienentämisen ennen sen lataamista, jolloin vain tarvittavat osat kuvasta ladataan ja säästetään muistia.

Kuvan skaalaus käytännössä

Skalauksessa käytettävä tärkein metodi on loadSampledResource(), joka käyttää BitmapFactory.Options-objektia kuvan koon tarkistamiseen ennen sen lataamista. Ensimmäinen vaihe on määrittää kuvan alkuperäinen koko ja arvioida, kuinka paljon kuva tulisi pienentää, jotta se mahtuu haluttuun tilaan ilman, että se ylittää laitteelle varattua muistirajoitusta.

Esimerkkinä, jos alkuperäinen kuva on erittäin suuri, kuten 6000x4000 pikseliä, ja halutaan näyttää se pienempänä pikkukuvana, voidaan laskea kuinka paljon kokoa tulee pienentää. Tämä voidaan tehdä asettamalla inSampleSize-arvo, joka määrittää kuvan kokonaissuhteen. Jos asetetaan inSampleSize = 2, kuva pienenee puoleen alkuperäisestä koosta, ja jos asetetaan inSampleSize = 4, se pienenee neljäsosaan alkuperäisestä.

Tarkoitus ja prosessi

Kun tiedämme alkuperäisen kuvan koon, voimme laskea optimaalisen skaalauskokoarvon käyttämällä seuraavaa koodia:

java
while ((originalHeight / (inSampleSize * 2)) > targetHeight && (originalWidth / (inSampleSize * 2)) > targetWidth) { inSampleSize *= 2; }

Tämä tarkistaa, ettei kuvan pienentäminen ylitä haluttuja korkeuden ja leveyden rajoja, ja toistaa tämän prosessin, kunnes optimaalinen inSampleSize-arvo on löytynyt. Kun oikea skaalauskerroin on löydetty, asetetaan tämä arvo ja lataamme kuvan pienennettynä.

Kuvan lataaminen taustalla

Kuvien käsittely, erityisesti suurten kuvien lataaminen ja skaalaaminen, on muistia ja prosessoria kuormittavaa, mikä voi johtaa sovelluksen hidastumiseen tai jopa sen kaatumiseen, jos se tehdään pääsäikeessä. Tämän vuoksi on suositeltavaa suorittaa tällaiset kuvanmuokkaustoiminnot taustasäikeessä, jotta käyttäjäkokemus ei kärsi. Voimme käyttää Androidin AsyncTask-luokkaa tai kolmannen osapuolen kirjastoja, kuten Picasso tai Volley, jotka on suunniteltu nopeaa ja tehokasta kuvien lataamista ja käsittelyä varten.

On myös tärkeää huomata, että vaikka kuvaa skaalattaessa voidaan määrittää sen tavoitekoko (esimerkiksi 100x100 pikseliä), tämä ei tarkoita sitä, että itse kuvan alkuperäinen koko muutetaan. Kuvan koko voi edelleen olla suurempi muistissa, mutta sitä ei tarvitse ladata kokoaan vastaavana, vaan vain sen tarvitsemat osat.

Muita huomioita ja suosituksia

Kuvien skaalaaminen ei ole ainoa tapa hallita muistinkulutusta. Käytettävissä on monia muita tehokkaita tekniikoita ja kirjastoja, jotka voivat auttaa parantamaan kuvan käsittelyä ja optimointia. Esimerkiksi:

  • Picasso on suosittu ja tehokas kirjasto, joka voi ladata ja välimuistittaa kuvia taustalla.

  • Android Universal Image Loader tarjoaa joustavan ja tehokkaan tavan käsitellä kuvia Androidissa.

  • Volley voi olla hyvä valinta, kun täytyy ladata kuvia nopeasti verkon kautta ja käsitellä niitä tehokkaasti.

Kaiken kaikkiaan kuvan käsittelyn tehokkuus ja muistin hallinta ovat tärkeitä osia Android-sovellusten suorituskyvyn optimoinnissa. Lataamalla vain tarvittavat kuvan osat ja suorittamalla raskaat laskentatehtävät taustalla, voidaan välttää OOM-virheitä ja varmistaa sujuva käyttäjäkokemus.

Miten Volley-kirjaston käyttö parantaa verkkopyyntöjen hallintaa Android-sovelluksissa?

Android-alustalla verkkopyyntöjen käsittely on keskeinen osa monia sovelluksia. Historiallisesti suosituimpia kirjastoja ovat olleet Apache HttpClient ja HttpURLConnection, mutta Androidin kehityksen myötä tilanne on muuttunut. Apache HttpClient oli pitkään suositeltu kirjasto, mutta Android 6.0:ssa sen tuki poistettiin kokonaan, ja tilalle tuli HttpURLConnection, joka on yhä käytössä nykyään. Vaikka HttpURLConnection toimii edelleen, se ei ole kaikilta osin käyttäjäystävällinen, erityisesti niille, jotka ovat uusia verkkopyyntöjen kirjoittamisessa. Lisäksi sen käyttö vaatii usein monimutkaista ja toistuvaa koodia, mikä voi tehdä sovelluksen kehittämisestä hankalaa.

Ratkaisu tähän haasteeseen tuli Googlelta, joka esitteli uuden kirjaston nimeltä Volley. Volley on yksinkertaistettu käyttöliittymä verkkopyyntöjen tekemiseen, joka helpottaa kehittäjien työtä. Vaikka Volley käyttää taustalla edelleen HttpURLConnection-kirjastoa, se tarjoaa merkittäviä etuja verrattuna perinteiseen lähestymistapaan.

Volley-kirjaston käyttöönotto tuo mukanaan useita etuja. Ensinnäkin, se hallitsee taustaprosessit ja lataa verkkopyynnöt erillisille säikeille. Tämä parantaa sovelluksen suorituskykyä ja estää UI-säikeen tukkeutumisen. Lisäksi Volleyn tarjoama välimuisti mekanismi mahdollistaa tiedon tallentamisen levylle ja välimuistin tehokkaan käytön. Tämän lisäksi pyynnöt voidaan priorisoida, mikä on tärkeää tilanteissa, joissa useita pyyntöjä tehdään samanaikaisesti.

Yksi Volleyn suurimmista eduista on sen yksinkertaisuus verrattuna HttpURLConnectioniin. Volley vähentää merkittävästi tarvittavaa koodia, sillä monimutkaiset virheenkäsittelyrutiinit ja toistuvat koodirakenteet on piilotettu kirjaston sisään. Tämä mahdollistaa kehittäjille keskittymisen varsinaiseen sovelluksen logiikkaan, eikä heidän tarvitse murehtia teknisistä yksityiskohdista, kuten virheenkäsittelystä tai pyynnön aikarajoista.

Volley tukee erilaisia pyynnön tyyppejä, kuten merkkijonoja (String), JSON-objekteja, kuvia ja mukautettuja pyynnön muotoja. Tämä tekee siitä monipuolisen työkalun, joka kattaa useimmat tavallisimmat sovellusten verkkopyyntötarpeet. Kuitenkin Volleyn kyvyt eivät ole rajattomat: se ei sovellu suurten tiedostojen lataamiseen, koska kaikki vastaanotetut objektit käsitellään muistissa, mikä voi aiheuttaa suorituskykyongelmia suurilla datamäärillä. Suurten tiedostojen lataamiseen suositellaan käytettäväksi Androidin DownloadManageria, joka on suunniteltu tätä varten.

Koska Volley ei ole osa Androidin SDK:ta, se täytyy ladata erikseen ja lisätä projektiin. Asennusprosessi alkaa Volleyn lähdekoodin lataamisella, ja sen jälkeen se integroidaan Android Studioon. Asennuksen jälkeen voidaan luoda yksinkertainen sovellus, joka tekee verkkopyynnön. Esimerkiksi, voimme luoda painikkeen, joka laukaisee pyyntöön liittyvän toiminnon ja näyttää tuloksen käyttöliittymässä.

Volleyn peruskäyttö on yksinkertaista: ensin luodaan RequestQueue-instanssi, sitten luodaan pyyntötyyppi, kuten StringRequest, joka lisätään jonoon. Kun pyyntö on valmis, voidaan käsitellä sen vastaus tai virhe. Esimerkiksi, jos haluamme ladata verkkosivun sisällön merkkijonona, voimme määrittää sen URL-osoitteen ja käsitellä tulokset suoraan onResponse-metodissa.

Volley tarjoaa myös mahdollisuuden peruuttaa pyynnön, mikä on tärkeää, jos pyyntö ei ole enää tarpeellinen, kuten tilanteessa, jossa käyttäjä selaa ListView-komponenttia ja pyyntöjä suoritetaan jatkuvasti. Tällöin turhien pyyntöjen jättämiselle voidaan estää ja säästää kaistanleveyttä, akkua ja suoritinresursseja.

On myös tärkeää huomioida, että vaikka Volley on tehokas työkalu pieniin ja keskikokoisiin pyyntöihin, sen rajoitukset suurten tiedostojen lataamisessa ja suoratoistosisällön käsittelyssä tarkoittavat, että se ei ole aina paras valinta kaikkeen verkkoliikenteeseen. Tällöin HttpURLConnection voi olla parempi vaihtoehto erityisesti suoratoistossa, jossa tiedon käsittely reaaliaikaisesti on välttämätöntä.