160 likes | 273 Views
Programowalne usługi. Jarosław Błażejczyk. Usługi działające w tle.
E N D
Programowalne usługi Jarosław Błażejczyk
Usługi działające w tle Dużym ograniczeniem telefonów komórkowych jest rozmiar ich wyświetlacza. I w zasadzie jest to największy problem, z którym w jakiś sposób muszą poradzić sobie aplikacje stworzone pod system Android. Jako, że na dzień dzisiejszy platforma ta w przeważającej ilości instalowana jest na urządzeniach mobilnych, obok optymalizacji programu do zmniejszenia zużycia baterii, "zmieszczenie się" na małym wyświetlaczu jest głównym celem podczas tworzenia wszelkich projektów. Ponadto należy również pamiętać o tym, że pomimo wielowątkowości jaka jest wspierana przez Androida, najczęściej widoczna jest tylko jedna aplikacja, z której właśnie korzystamy.
Usługi działające w tle • Usługi (ang. Services) stanowią w Androidzie jeden z elementów budulcowych aplikacji. • Jako klasa bazowa Service dziedziczy po klasie Context (podobnie jak klasa Activity). • Usługa działająca w tle ma większy priorytet niż Aktywność, która w tym samym momencie jest nieaktywna/niewidoczna. Wiąże się to z tym, że podczas zwalniania zasobów systemowych pierwszym kandydatem do zatrzymania i usunięcia z pamięci będzie niewidoczna Aktywność. Zatrzymywanie usługi następuje tylko wtedy, gdy zajmuje ona zasób niezbędny do otwarcia Aktywności. Jednak wtedy system przywraca usługę do działania zaraz po tym, gdy zasób ten będzie ponownie dostępny.
Usługi działające w tle • Usługa nie jest osobnym procesem ani wątkiem! Należy pamiętać, że wykonywana jest w głównym wątku naszej aplikacji. Dlatego też ważnym jest by wszystkie zasobożerne czynności przenosić do osobnych wątków, tak by zapewnić głównemu wątkowi ciągłą gotowość na odpowiedź. • Brak interfejsu usług sprawia, że sterowaniem ich cyklem życia zajmują się inne komponenty systemu.
Usługi działające w tle • Ogólnie rzecz biorąc jest to kod, który działa nieprzerwanie przez jakiś okres czasu (czas życia aplikacji), nie zawiera interfejsu użytkownika (UI) i nie oddziałuje bezpośrednio z użytkownikiem. • Przykładowo tworząc odtwarzacz multimedialny mielibyśmy kilka aktywności pozwalających wybrać listę piosenek do odtwarzania, lecz samo ich odtwarzanie powinno być obsługiwane przez usługę, która będzie działać nawet po przejściu do innych ekranów (aktywności) w obrębie aplikacji.
Uruchomienie usługi • Aby uruchomić usługę, niezależnie od innych usług i aktywności w celu wykonania jakichś operacji - wywołujemy metodę Context.startService(). • Aby umożliwić aplikacji odsłonięcie niektórych z jej funkcjonalności (API) dla innych aplikacji za pomocą interfejsu AIDL (Android Interface Definition Language) - używamy metodyContext.bindService(), która umożliwia nawiązanie połączenia z naszą usługą (uruchomienia jej o ile jest taka konieczność). Ten typ usług określa się mianem związanych (ang. bound services). • Aby zatrzymać usługę - używamy metody Context.stopService().
Deklaracja usług • onBind() - metoda używana jest w przypadku związanych usług, jako parametr przyjmuje intencję (poprzez metodę bindService()). W przypadku gdy korzystamy z usług niezwiązanych - wystarczy, że zwrócimy tutaj null. • onCreate() - wywoływana, gdy usługa jest tworzona po raz pierwszy, tu także umieszczamy kod, który chcemy wywołać tylko raz,
Deklaracja usług • onStartCommand() - metoda wywoływana za każdym razem, gdy pojawi się intencja przesłana poprzez metodę startService(), • onDestroy() - wywoływana gdy usługa jest zakończona (przez system albo na żądanie poprzez stopService()). Nawet jeśli usługa została wywołana kilka razy (za pomocą onStartCommand()) - zostanie ona definitywnie zniszczona.
Kod pliku main.xml <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/tvServiceControl" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sterowanie usługą działającą w tle" android:textSize="18px" android:layout_gravity="center"/>
Kod pliku main.xml <Button android:id="@+id/btnStartService" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Start" android:layout_gravity="center" /> <Button android:id="@+id/btnStopService" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Stop" android:layout_gravity="center" /></LinearLayout>
Kompletny kod źródłowy ClientActivity.java: package com.froger.servicespresentation; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class ClientActivity extends Activity { private Button btnStartService; private Button btnStopService;
Kompletny kod źródłowy ClientActivity.java: private OnClickListener startServiceListener = newOnClickListener() { @Override public void onClick(View arg0) { startService(new Intent(ClientActivity.this, MyService.class)); } }; private OnClickListener stopServiceListener = new OnClickListener() { @Override public void onClick(View arg0) { stopService(new Intent(ClientActivity.this, MyService.class)); } };
Kompletny kod źródłowy ClientActivity.java: /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnStartService = (Button)findViewById(R.id.btnStartService); btnStopService =(Button)findViewById(R.id.btnStopService); btnStartService.setOnClickListener(startServiceListener); btnStopService.setOnClickListener(stopServiceListener); }}
Druga aktywność MyService.java Packagecom.froger.servicespresentation;import java.util.Timer;import java.util.TimerTask;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.widget.Toast;
Druga aktywność MyService.java public class MyService extends Service { private Toast myToast; private Timer updatingTimer; private TimerTask notify = new TimerTask() { @Override public void run() { myToast.setText("Usługa ciągle działa"); myToast.show(); } }; @Override public void onCreate() { super.onCreate(); updatingTimer = new Timer(); myToast = Toast.makeText(getApplicationContext(), "Usługa została uruchomiona", Toast.LENGTH_SHORT); myToast.show(); }
Druga aktywność MyService.java @Override public void onDestroy() { updatingTimer.cancel(); myToast.setText("Usługa została zatrzymana"); myToast.show(); super.onDestroy(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); updatingTimer.scheduleAtFixedRate(notify, 5*1000, 5*1000); } @Override public IBinder onBind(Intent arg0) { return null; }}