Programowalne usługi

Download Report

Transcript Programowalne usługi

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/and
roid" 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 {
btnStartService;
private Button btnStopService;
private Button
Kompletny kod źródłowy
ClientActivity.java:
private OnClickListener startServiceListener = new
OnClickListener() {
@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
Package
com.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; }}