You are on page 1of 84

Razvoj mobilnih aplikacija

Predavanje 6

Doc.dr.sc. Josip Balen


Aktivnosti (Activities)
Aktivnosti
• komponenta aplikacije koja prikazuje sadržaj na zaslonu uređaja s kojim
korisnik može vršiti interakciju za obavljanje nekog zadatka ili posla
▫ zvanje telefonom, fotografiranje, slanje e-maila, pregledavanje mape
• svaka aktivnost dobiva prozor na kojem se može nacrtati korisničko
sučelje
• prozor najčešće zauzima cijeli zaslon, ali može biti i manji i plutati iznad
drugih prozora
• postoji životni krug aplikacija
• metode se pozivaju kada aktivnost prelazi iz jednog stanja u drugo
Aktivnosti
• aplikacija se obično sastoji od više aktivnosti koje su povezane
• najčešće postoji jedna “glavna” aktivnost
▫ tako se i zove
▫ početni prozor nakon što korisnik pokrene aplikaciju
▫ svaka aktivnost može pokrenuti neku drugu aktivnost
▫ novopokrenuta aktivnost zaustavlja prethodnu
▫ zaustavljene aktivnosti se čuvaju na stogu
▫ novopokrenuta aktivnost je na vrhu stoga i ima fokus
▫ stog - LIFO
Kreiranje aktivnosti
• kreiranje podklase iz klase Activity
• implementiranje pozivnih metoda koje se pozivaju kada aktivnost
mijenja status u životnom ciklusu

• public class MainActivity extends AppCompatActivity {


▫ @Override
▫ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); } }
Kreiranje aktivnosti
▫ dvije najznačajnije metode:
▫ onCreate()
 mora se implementirati
 poziva se kada se kreira aktivnost
 inicijalizacija važnih komponenti
 poziva se setContentView() kojom se definira izgled korisničkog sučelja

▫ onPause()
 sustav poziva ovu metodu na prvi znak korisnikovog napuštanja aktivnosti – ne znači
uništavanje aktivnosti
 pohranjivanje promjena koje se trebaju sačuvati do povratka na aktivnost
Implementacija korisničkog sučelja
• korisničko sučelje aktivnosti je osigurano hijerarhijom pogleda (view)
▫ objekt izveden iz klase View
▫ svaki pogled kontrolira određeno pravokutno područje unutar prozora
aktivnosti i odgovara na interakciju korisnika
 dugme koje aktivira akciju kada ga korisnik pritisne
• Layouti – način organizacije potomaka pogleda
• najčešći način definiranja korisničkog sučelja: upotreba XML datoteke
▫ odvojen programski kôd od dizajna
Implementacija korisničkog sučelja
• Automatski import u MainActivity.java:
▫ import android.support.v7.app.AppCompatActivity;
▫ import android.os.Bundle;
▫ import android.view.View;
▫ import android.widget.Button;
▫ import android.widget.TextView;
Deklaracija aktivnosti u manifestu
• aktivnost mora biti deklarirana u manifest datoteci
kako bi bila vidljiva sustavu

<?xml version="1.0" encoding="utf-8"?>


<manifest ... >
    <application android:icon="@drawable/app_icon.png" ... >
        <activity android:name="com.example.project.ExampleActivity"
                  android:label="@string/example_label" ... >
        </activity>
        ...
    </application>
</manifest>
Upotreba intent filtra
• deklaracija kako druge komponente aplikacije mogu aktivirati
aktivnost
• kada se kreira nova aplikacija upotrebom Android SDK alata,
jedina aktivnost koja je automatski kreirana uključuje intent filter
▫ deklarira ju smjestiti u kategoriju da aktivnost odgovara na “glavnu”
akciju i treba za pokretanje
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
Pokretanje aktivnosti
• druge aktivnosti (unutar aplikacije) se mogu
pokrenuti pozivom startActivity()
▫ prosljeđuje joj se intent koji opisuje aktivnost koju
treba pokrenuti
 točna aktivnost ili opis tipa akcije

Intent intent = new Intent(this, SignInActivity.class);


startActivity(intent);
Pokretanje aktivnosti
• korisnikova aplikacija možda zatreba odraditi neke radnje – slanje e-
maila, SMS, prijavu statusa
• ako aplikacija nema svoje aktivnosti, može podići aktivnosti iz drugih
aplikacija na uređaju
• kreira se intent koji opisuje radnju koju je potrebno obaviti – sustav
pokreće odgovarajuću aktivnost
Pokretanje aktivnosti
• EXTRA_EMAIL – polje e-mail adresa
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
Pokretanje aktivnosti za rezultat
• prihvaćanje rezultata od aktivnosti koja je pokrenuta
• startActivityForResult()
• nakon poziva metode implementira se metoda
onActivityResult()
Gašenje aktivnosti
• poziv finish() metode

• poziv finish() u onCreate():


• onCreate() -> onDestroy()
• poziv finish() u onStart():
• onCreate() -> onStart() -> onStop() -> onDestroy()
• poziv finish() u onResume():
• onCreate() -> onStart() -> onResume() -> onPause() -> onStop() ->
onDestroy()
Životni ciklus aktivnosti
• upravljanje životnim ciklusom aktivnosti implementacijom pozivnih
metoda je važan u razvoju jake i fleksibilne aplikacije
• životni ciklus aktivnosti je direktno povezan s drugim aktivnostima
• tri moguća stanja aktivnosti:

• resumed
▫ aktivnost je u prvom planu (foreground) na zaslonu i ima korisnikov fokus
Životni ciklus aktivnosti
• paused
▫ druga aktivnost je u prvom planu i ima korisnikov fokus, ali je još vidljiva
▫ nova aktivnost (prikaz na zaslonu) je djelomično prozirna ili ne prekriva
cijeli ekran
▫ pauzirana aktivnost potpuno živa (Activity objekt je ostao u memoriji,
održavaju se informacije o svim stanjima i članovima)
▫ aktivnost je još uvijek povezana s upraviteljem prozora
▫ aktivnost može biti ubijena u slučaju manjka slobodne memorije
Životni ciklus aktivnosti
• stopped
▫ Aktivnost je u pozadini
▫ prikaz aktivnosti na zaslonu je u potpunosti zaklonjen prikazom neke druge
aktivnosti
▫ objekt je ostao u memoriji, održavaju se informacije o svim stanjima i
članovima
▫ aktivnost više nije povezana s upraviteljem prozora
▫ aktivnost može biti ubijena u slučaju manjka slobodne memorije
Implementacija poziva u životnom ciklusu
• prijelaz aktivnosti iz jednog stanja u neko drugo popraćen je pozivnim
metodama
• svaka od metoda se može prepisati (engl. override)
public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // The activity is being created.
  }
    @Override
    protected void onStart() {
        super.onStart();
        // The activity is about to become visible.
  }
    @Override
    protected void onResume() {
        super.onResume();
        // The activity has become visible (it is now "resumed").
  }
    @Override
    protected void onPause() {
        super.onPause();
        // Another activity is taking focus (this activity is about to be "paused").
  }
    @Override
    protected void onStop() {
        super.onStop();
        // The activity is no longer visible (it is now "stopped")
  }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // The activity is about to be destroyed.
  }
}
Početak

Korisnik se vraća
onCreate()
nazad na aktivnost

onStart() onRestart()

Proces ubijen onResume()

Izvršava se Aktivnost dolazi


u prvi plan

Druga aktivnost
dolazi u prvi plan

Druga aplikacija
onPause()
treba memoriju
Aktivnost dolazi
Aktivnost nije više vidljiva u prvi plan

onStop()

Aktivnost je završili ili ju je sustav uništio

onDestroy() Ugašena
Implementacija poziva u životnom ciklusu
• postoje tri petlje kroz koje aktivnost može prolaziti
▫ cijeli život
 odvija se između prvog poziva onCreate() i zadnjeg (konačnog) poziva onDestroy()
 aktivnost odrađuje globalno podešavanje u onCreate(), a otpušta sve zauzete resurse
u onDestroy()
▫ vidljivi život
 aktivnost se izvršava između onStart() i onStop() metoda
 za ovo vrijeme korisnik može vidjeti prikaz aktivnosti na zaslonu – iako ne mora biti
fokusirana i imati interakciju s korisnikom
 između navedenih metoda može se upravljati potrebnim resursima za prikaz i izvršavanje
aktivnosti
Implementacija poziva u životnom ciklusu
▫ život u fokusu (foreground)
 započinje pozivom onResume(), a završava pozivom onPause()
 za ovo vrijeme aktivnost je ispred svih drugih aktivnosti i u interakciji s
korisnikom
 normalno je ponavljanje ove petlje više puta za neku aktivnost
Implementacija poziva u životnom ciklusu
• pregled životnog ciklusa neke aktivnosti
▫ onCreate()
 poziva se kada se aktivnost prvi puta kreira
 inicijalizacija varijabli članova klase
 onStart() je metoda koja se slijedeća poziva
 mogućnost ubijanja aktivnosti: NE
 slijedeća metoda: onStart()
▫ onRestart()
 poziva se nakon što je aktivnost zaustavljena, a prije ponovnog pokretanja
 onStart() je metoda koja se slijedeća poziva
 mogućnost ubijanja aktivnosti: NE
 slijedeća metoda: onStart()
Implementacija poziva u životnom ciklusu
▫ onStart()
 poziva se kada aktivnost treba postati vidljiva korisniku
 nakon nje mogu slijediti onResume() ako se aktivnost postavlja u prvi plan ili
onStop() ako postaje skrivena korisniku
 mogućnost ubijanja aktivnosti: NE
 slijedeće metode: onResume() ili onStop()
▫ onResume()
 poziva se kada aktivnost treba biti u mogućnosti obavljati interakciju s korisnikom
 aktivnost je na vrhu stoga
 mogućnost ubijanja aktivnosti: NE
 slijedeća metoda: onPause()
Implementacija poziva u životnom ciklusu
▫ onPause()
 poziva se kada sustav treba nastaviti neku prethodnu aktivnost (resume) ili je
korisnik zatražio navigaciju do nekog drugog dijela sustava (Home)
 ovo stanje se obično koristi za pohranu promjena podataka koji se trebaju
sačuvati
 ako aktivnost treba vratiti u prvi plan, poziva se onResume()
 ako aktivnost postaje skrivena korisniku, poziva se onStop()
 mogućnost ubijanja aktivnosti: DA
 slijedeće metode: onResume() ili onStop()
Implementacija poziva u životnom ciklusu
▫ onStop()
 poziva se kada aktivnost više nije vidljiva korisniku jer se nastavila neka druga
aktivnost koja zaklanja ovu
 započinje neka nova aktivnost ili se nastavlja neka sa stoga
 slijede onRestart() ako treba obaviti interakciju s korisnikom ili
onDestroy() ako treba završiti aktivnost
 mogućnost ubijanja aktivnosti: DA
 slijedeće metode: onRestart() ili onDestroy()
Implementacija poziva u životnom ciklusu
▫ onDestroy()
 zadnji poziv koji se obavi prije uništenja aktivnosti
 poziva se jer je aktivnost završila (poziv finish() metode ili OS privremeno
uništava aktivnost kako bi dobio potrebne resurse)
 dva navedena procesa se mogu razlikovati pozivom isFinished() metode
koja se često koristi u onPause() – određivanje da li je aktivnost pauzirana ili
uništena
 mogućnost ubijanja aktivnosti: DA
 slijedeća metoda: nema
Spremanje stanja aktivnosti
• ako sustav uništi aktivnost zbog oslobađanja memorije – Activity
objekt se uništava
▫ sustav ne može samo nastaviti aktivnost kao da je netaknuta
▫ Activity objekt se mora ponovno kreirati
▫ korisnik najčešće ne primjećuje cijeli proces
• najvažnije informacije o stanju aktivnosti se mogu sačuvati
▫ poziv metode onSaveInstanceState()
Spremanje stanja aktivnosti
• sustav poziva metodu za snimanje stanja prije nego što aktivnost
postane uništiva
• metodi se šalje argument Bundle u koji se mogu pohraniti bitne
informacije u obliku ime-vrijednost
▫ metode putString() i putInt()
• ako sustav ubije aktivnost, a korisnik nakon toga poželi ponovno
nastaviti rad aktivnosti, Bundle se šalje metodama onCreate() i
onRestoreInstanceState()
Spremanje stanja aktivnosti
Aktivnost se
izvršava
onCreate() ili
onSaveInstanceState() Instanca aktivnosti je
nedirnuta; nema
Spremanje stanja aktivnosti potrebe ponovno ju
Druga aktivnost dolazi u
prvi plan kreirati

Korisnik ponovno
pokreće aktivnost
onRestart()
onSaveInstanceState()
Proces ubijen* Spremanje stanja aktivnosti
Druga aktivnost dolazi u
prvi plan
Aplikacija višeg prioriteta Aktivnost nije
treba memoriju vidljiva
*instanca aktivnosti je uništena,
ali je stanje pohranjeno
Spremanje stanja aktivnosti
• ne postoji jamstvo da će onSaveInstanceState() biti pozvana prije
uništenja aktivnosti
▫ nema potrebe zapamtiti stanje
▫ poziva se prije onStop() i možda prije onPause()
• u slučaju izostanka implementacije metode za snimanje stanja, neka stanja
aktivnosti se vraćaju podrazumijevanom implementacijom metode u Activity
▫ za svaki prikaz (View) svaka promjena korisničkog sučelja se snima i vraća kada se
aktivnost reaktivira
▫ primjer: EditText ili CheckBox
▫ programer mora osigurati jedinstveni ID (android:id atribut) za svaki widget kojem
treba pamtiti stanje
Spremanje stanja aktivnosti
• u slučaju prepisivanja metode za snimanje stanja aktivnosti – prvo
pozvati superklasu
super.onSaveInstanceState();
• isto vrijedi i za vraćanje stanja aktivnosti
• brz način provjere rada spremanja stanja aktivnosti
▫ rotacija uređaja – promjena orijentacije zaslona
▫ aktivnost se uništava i stvara se nova za drugu orijentaciju zaslona
Rukovanje promjenama konfiguracije
• promjene se mogu dogoditi i za vrijeme rada aplikacije
▫ orijentacija zaslona, prikaz tipkovnice, jezik
• Android ponovno kreira aktivnost koja se izvršava
▫ poziva se onDestroy() i odmah zatim onCreate()
• takvo ponašanje pomaže prilagodbi aplikacije na promjene
Koordiniranje aktivnosti
• kada jedna aktivnost pokrene drugu obje prolaze promjene životnog
ciklusa
• prva aktivnost se pauzira i zaustavlja (ne mora se zaustaviti ako je
vidljiva u pozadini) dok se kreira druga aktivnost
• u slučaju da aktivnosti dijele snimljene podatke važno je razumjeti da
prva aktivnost nije u potpunosti zaustavljena dok se druga nije kreirala
• proces pokretanja nove aktivnosti se preklapa s procesom zaustavljanja
prve
Koordiniranje aktivnosti
• redoslijed poziva u životnom ciklusu je dobro definiran, pogotovo ako su
dvije aktivnosti dio istog procesa i jedna pokreće drugu
• primjer kada aktivnost A pokreće aktivnost B
1. izvršava se metoda onPause() aktivnosti A
2. izvršavaju se redom za aktivnost B: onCreate(), onStart() i
onResume() (aktivnost B ima korisnikov fokus)
3. ako aktivnost A nije vidljiva na zaslonu, izvršava se njena onStop()
metoda
Koordiniranje aktivnosti
• ako aktivnost B treba podatke koje u bazu zapisuje aktivnost A
• u kojoj metodi aktivnosti A napisati programski kôd?

• onPause()
Fragmenti

*slika preuzeta s https://twitter.com/androidfragment


Fragmenti
• ponašanje ili dio korisničkog sučelja u aktivnosti
• više fragmenata se može kombinirati u jednu aktivnost i napraviti multi-
pane UI i koristiti fragmente u više aktivnosti
• modularni dio aktivnosti
• ima svoj vlastiti životni ciklus
• prima svoje ulazne događaje
Fragmenti
• mora biti ugrađen u aktivnost
• na životni ciklus fragmenta utječe životni ciklus aktivnosti čiji je dio
▫ ako je aktivnost pauzirana, i fragment je također
• dok se aktivnost izvršava (radi) svakim fragmentom se može rukovati
neovisno
• fragmenti mogu ići na stog kao aktivnosti
• kada se fragment doda kao dio prikaza aktivnosti, ima svoj život unutar
ViewGroup u hijerarhiji aktivnosti i fragment definira svoj prikaz
Fragmenti
• elementom <fragment> umeće se u xml datoteku
aktivnosti (kao fiksni element)
• dinamička upotreba - korištenjem klase
FragmentManager koja omogućuje dodavanje,
uklanjanje ili izmjenu tijekom izvođenja aplikacije
• fragment ne mora imati UI – može obavljati posao kao
nevidljivi radnik
• na slici je prikazan životni ciklus fragmenta kada je
aktivnost pokrenuta
Filozofija dizajna
• fragmenti su uvedeni u Android inačici 3.0 (API razine 11)
• cilj – bolja podrška dinamičkim i fleksibilnim UI na većim zaslonima – tableti
• fragmenti omogućuju dizajn UI bez potrebe kompleksnog upravljanja
hijerarhije prikaza
• primjer:
▫ aplikacija za prikaz vijesti
▫ jedan fragment pokazuje listu članaka – lijevo
▫ drugi fragment prikazuje sadržaj članka – desno
▫ oba fragmenta su dio iste aktivnosti
▫ svaki fragment ima svoje metode životnog ciklusa
Filozofija dizajna
Kreiranje fragmenta
• za kreiranje fragmenta potrebno je napraviti
podklasu klase Fragment
• klasa treba sadržavati metode kao aktivnost
▫ onCreate(), onStart(), onPause() i
onStop()
• ako se prepravlja aplikacija za korištenje fragmenata,
kôd metoda iz aktivnosti može se prebaciti u
fragmente
Kreiranje fragmenta
• najčešće je potrebno implementirati barem slijedeće metode (za svaki
fragment):
▫ onCreate()
▫ onCreateView()
▫ onPause()
Kreiranje fragmenta
• neke podklase koje se mogu naslijediti:
▫ DialogFragment
 prikazuje plutajući dijalog
▫ ListFragment
▫ PreferenceFragment
Dodavanje UI-ja
• fragment se obično koristi kao dio UI-ja aktivnosti i pridonosi svojim
prikazom u aktivnosti
• za realizaciju prikaza fragmenta treba implementirati pozivnu metodu
onCreateView()
▫ Android ju poziva kada treba nacrtati prikaz fragmenta
▫ implementacija mora vratiti View kao rezultat
Dodavanje UI-ja
• primjer podklase klase Fragment koja učitava
prikaz iz datoteke

public static class ExampleFragment extends Fragment {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.example_fragment, container, false);
  }
}
Dodavanje fragmenta u aktivnost
• dva načina dodavanja:
▫ datoteka za prikaz (layout)
▫ programsko dodavanje pisanjem kôda
 fragment se može dodati u prikaz aktivnosti u bilo koje vrijeme dok se aktivnost
izvršava
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="com.example.news.ArticleListFragment"
            android:id="@+id/list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="com.example.news.ArticleReaderFragment"
            android:id="@+id/viewer"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>
Dodavanje fragmenta u aktivnost
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();

ExampleFragment fragment = new ExampleFragment();


fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

• prvi argument add metode je ViewGroup u koji se


treba smjestiti fragment (ID)
Dodavanje fragmenta bez UI
• add(Fragment, String)
▫ dodaje fragment za koji se ne poziva onCreateView()
• findFragmentByTag()
▫ pristup fragmentu iz aktivnosti
Upravljanje fragmentima
• potrebno je koristiti FragmentManager objekt
• potrebno je pozvati getFragmentManager() iz aktivnosti
• neke mogućnosti:
▫ dohvaćanje fragmenata koji postoje u aktivnosti –
findFragmentById() ili findFragmentByTag()
▫ poziv (pop) fragmenata sa stoga – popBackStack()
▫ registriranje slušatelja (listener) za promjene unazad na stogu –
addOnBackStackChangedListener()
Izvođenje transakcija fragmenata
• svaki skup promjena koji se provodi u aktivnosti zove se transakcija
• provodi se pomoću FragmentTransaction
• svaka transakcija se može snimiti na stog koji upravlja aktivnostima
▫ promjene: add(), remove(), replace()
• sve promjene prije commit() se smatraju jednom transakcijom
Izvođenje transakcija fragmenata
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,


// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction


transaction.commit();
Komunikacija s aktivnostima
• iako je Fragment implementacija objekta nezavisna
o Activity i može se koristiti u više aktivnosti,
instanca fragmenta je direktno povezana s aktivnosti
koja ga sadrži
• fragment može pristupiti instanci aktivnosti
metodom getActivity()
View listView = getActivity().findViewById(R.id.list);
Komunikacija s aktivnostima
• isto tako aktivnost može pozivati metode iz fragmenata postavljanjem
reference na fragment

ExampleFragment fragment = (ExampleFragment)


getFragmentManager().findFragmentById(R.id.example_fragment);
Upravljanje životnim ciklusom fragmenta

• slično kao kod aktivnosti


• tri stanja:
▫ resumed
▫ paused
▫ stopped
• životni ciklus aktivnosti
utječe na životni ciklus
fragmenata
• ako aktivnost primi
onPause()i svaki fragment
te aktivnosti prima isti poziv
Upravljanje životnim ciklusom fragmenta
• fragmenti imaju još neke pozive:
▫ onAttach()
 poziva se kada je fragment povezan s aktivnosti
▫ onCreateView()
 poziva se za kreiranje prikaza vezanog za fragment
▫ onActivityCreated()
 poziva se kada se vrati iz onCreate() aktivnosti
▫ onDestroyView()
 poziva se kada prikaz vezan uz fragment treba ukloniti
▫ onDetach()
 poziva se kada fragment treba prekinuti vezu s aktivnosti
Loaders

*slika preuzeta s http://android-kaizen.com/2016/01/04/loaders-in-android/


Loaderi
• olakšavaju asinkrono učitavanje podataka u fragment ili aktivnost
• uvedeni u inačicu Android 3.0
• značajke:
▫ dostupni u svim aktivnostima i fragmentima
▫ asinkrono učitavanje podataka
▫ prate izvor podatka i dostavljaju nove rezultate kada se kontekst promijeni
▫ automatski se ponovno spajaju na mjesto gdje su stali poslije ponovnog
kreiranja ako se konfiguracija promijeni
Loader API
• LoaderManager
▫ apstraktna klasa vezana uz Activity ili Fragment
▫ upravlja jednom ili više instanci Loader klase
▫ može biti samo jedan LoadManager po aktivnosti ili fragmentu, ali jedan
LoadManager može imati više loadera
• LoaderManager.LoaderCallbacks
▫ sučelje za poziv klijentu za interakciju s LoaderManager
▫ koristi se onCreateLoader() metoda za kreiranje novog loadera
Loader API
• Loader
▫ apstraktna osnovna klasa
• AsyncTaskLoader
▫ apstraktni loader
• CursorLoader
▫ podklasa klase AsyncTaskLoader koja šalje upit
ContentResolver, a vraća Cursor
Pokretanje Loadera
• inicijalizacija Loader-a se obično obavlja unutar metode aktivnosti
onCreate() ili fragmenta onActivityCreated()
// Prepare the loader.  Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);

• initLoader() ima tri argumenta:


▫ jedinstveni ID
▫ opcionalni argument
▫ implementacija LoaderManager.LoaderCallbacks koju LoadManager poziva i
izvještava o događajima
Pokretanje Loadera
• poziv initLoader() osigurava da je loader inicijaliziran i aktivan –
dva moguća ishoda:
▫ ako loader sa zadanim ID-em postoji, ponovno se koristi zadnji kreirani
▫ ako ne postoji, poziva se onCreateLoader()
Ponovno pokretanje Loadera
• odbacivanje starih podataka i ponovno pokretanje
• restartLoader()
public boolean onQueryTextChanged(String newText) {
// Called when the action bar search text has changed. Update
// the search filter, and restart the loader to do a new query
// with this filter.
mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
getLoaderManager().restartLoader(0, null, this);
return true;
}
Zadaci i stog
• aplikacija se obično sastoji od nekoliko aktivnosti
• svaka bi aktivnost trebala biti dizajnirana oko specifične vrste posla
• pokretanje aktivnosti iz drugih aplikacija (slanje e-maila)
• zadatak je skup aktivnosti s kojima korisnik vrši interakciju za obavljanje
nekog posla
▫ aktivnosti su organizirane u stog (engl. back stack)
• Home screen je početno mjesto za većinu zadataka
• kada jedna aktivnost pokrene drugu, nova dolazi na vrh stoga i preuzima
fokus
• stara aktivnost ostaje ispod na stogu - zaustavljena
Zadaci i stog
• kada korisnik pritisne dugme za povratak (Back)
▫ trenutna aktivnost se skida sa stoga – uništava
▫ prethodna aktivnost se nastavlja – vraća se UI te aktivnosti
• aktivnosti na stogu se NIKADA NE MIJEŠAJU
Zadaci i stog
Rukovanje zadacima
• mogućnosti:
▫ pokretanje novog zadatka kada se pokrene aktivnost
▫ stavljanje aktivnosti u isti zadatak
▫ postavljanje postojeće instance aktivnosti u fokus
▫ kreiranje nove instance aktivnosti
Rukovanje zadacima
• postavljanje atributa u <activity> u manifest datoteci:
▫ taskAffinity
▫ launchMode
▫ allowTaskReparenting
▫ clearTaskOnLaunch
▫ alwaysRetainTaskState
▫ finishOnTaskLaunch
Rukovanje zadacima
• postavljanje argumenta (flaga) u startActivity()
▫ FLAG_ACTIVITY_NEW_TASK
▫ FLAG_ACTIVITY_CLEAR_TOP
▫ FLAG_ACTIVITY_SINGLE_TOP
Definiranje načina pokretanja
U manifest datoteci
• launchmode atribut:
▫ “standard”
 sustav kreira novu instancu aktivnosti u zadatku u kojem je pokrenuta
 aktivnost se može instancirati više puta
 svaka instanca može pripadati drugom zadatku
 jedan zadatak može sadržavati više instanci
Definiranje načina pokretanja
U manifest datoteci
• launchmode atribut:
▫ “singleTop”
 ako već postoji instanca aktivnosti na vrhu zadatka, sustav preusmjerava intent
na tu instancu pomoću poziva metode onNewIntent()
 aktivnost se može instancirati više puta
 svaka instanca može pripadati drugom zadatku
 zadatak može sadržavati više instanci – samo ako instanca na vrhu NIJE
postojeća instanca aktivnosti
Definiranje načina pokretanja
U manifest datoteci
• launchmode atribut:
▫ “singleTask”
 sustav kreira novi zadatak i instancira aktivnost na vrhu
 ako već postoji instanca aktivnosti u drugom zadatku, sustav preusmjerava
intent na postojeću instancu pomoću onNewIntent()
Definiranje načina pokretanja
U manifest datoteci
• launchmode atribut:
▫ “singleInstance”
 sustav ne pokreće niti jednu drugu aktivnost u zadatku
 aktivnost je jedna i jedini član svog zadatka
 druge aktivnosti koje pokreće instanca ove aktivnosti se otvaraju u zasebnom
zadatku
Definiranje načina pokretanja
Definiranje načina pokretanja
Korištenjem Intent Flagova

• FLAG_ACTIVITY_NEW_TASK
▫ pokretanje aktivnosti u novom zadatku
▫ ako već radi zadatak za aktivnost koja se pokreće, zadatak se postavlja u
prvi plan sa povraćenim zadnjim stanjem, a aktivnost prima novi intent u
onNewIntent()
▫ kao “singleTask”
Definiranje načina pokretanja
Korištenjem Intent Flagova

• FLAG_ACTIVITY_SINGLE_TOP
▫ ako je aktivnost koja se pokreće trenutna aktivnost (na vrhu stoga),
postojeća instanca prima poziv u onNewIntent(), a ne kreira se nova
instanca aktivnosti
▫ kao “singleTop”
Definiranje načina pokretanja
Korištenjem Intent Flagova

• FLAG_ACTIVITY_CLEAR_TOP
▫ ako se aktivnost koja se pokreće već radi u trenutnom zadatku, umjesto
pokretanja nove instance aktivnosti, sve aktivnosti iznad ove se uništavaju a
intent se šalje nastavljenoj (resumed) instanci aktivnosti – na vrhu
▫ ne postoji alternativa za manifest
Rukovanje afinitetima
• afinitet označava kojem zadatku aktivnost preferira pripadati
• aktivnosti iste aplikacije međusobno imaju afinitet – preferiraju
pripadati istom zadatku
• podrazumijevani afinitet aktivnosti se može promijeniti
• aktivnosti definirane u različitim aplikacijama mogu dijeliti afinitet
• afinitet aktivnosti se može mijenjati atributom taskAffinity unutar
elementa <activity>
Brisanje stoga
• ako korisnik ostavi zadatak dulje vrijeme, sustav iz zadatka briše sve
aktivnosti osim glavne (root)
• atributi kojima se može modificirati ponašanje:
▫ alwaysRetainTaskState
 true – root aktivnost ne pokazuje ponašanje opisano gore
▫ clearTaskOnLaunch
 true – stog se briše do root aktivnosti uvijek kada korisnik napusti zadatak –
suprotno od gore navedenog atributa
▫ finishOnTaskLaunch
 kao clearTaskOnLaunch ali za jednu aktivnost, ne za zadatak
Pokretanje zadatka
• može se podesiti aktivnost kao početna točka za zadatak
• intent filter
"android.intent.action.MAIN“
"android.intent.category.LAUNCHER“
Pitanja?

You might also like