android chapter22-services

31
Android Services 22 Notes are based on: Android Developers http://developer.android.com/index.html

Upload: manhvokiem

Post on 02-Dec-2014

920 views

Category:

Education


2 download

DESCRIPTION

Giới thiệu về Services trong Android

TRANSCRIPT

Page 1: Android chapter22-services

Android Services

22

Notes are based on: Android Developers http://developer.android.com/index.html

Page 2: Android chapter22-services

222

22. Android Services

Services

2

Android Services

Một Service là một component ứng dụng chạy tại background, không tương tác với người dùng, chạy trong khoảng thời gian không xác định.

Service, cũng như các đối tượng ứng dụng khác (activitties, broadcast listeners…), chạy tại thread chính của tiến trình chủ.

Nghĩa là, nếu một service định làm gì đó chiếm CPU (chẳng hạn MP3 playback) hoặc đợi lâu (networking), nó nên tạo một thread riêng để làm việc đó.

Mỗi service phải có một khai báo <service> tại AndroidManifest.xml của package.

Service được gọi bằng Context.startService() và Context.bindService().

Page 3: Android chapter22-services

333

22. Android Services

Services

3

Android Services

• Đối với mỗi service, nhiều lời gọi Context.startService() chỉ dẫn đến việc phương thức onStartCommand() của Service class được gọi nhiều lần). Tuy nhiên, chỉ cần một lần Context.stopService() hay stopSelf() được gọi là đủ để kết thúc service đó.

• Một service có thể được khởi động và chạy cho đến khi nào ai đó dừng nó hoặc nó tự dừng.

Page 4: Android chapter22-services

444

22. Android Services

Services

4

Service Life Cycle

CŨng như activity, một service có các phương thức lifecycle mà ta cài để giám sát các thay đổi trạng thái của nó. Nhưng service có ít phương thức life cycle hơn, và chúng ở dạng public chứ không phải protected:

1. void onCreate ()

2. void onStartCommand (Intent intent,…)

3. void onDestroy ()

onCreate

onStart

onDestroy

Page 5: Android chapter22-services

555

22. Android Services

Services

5

Service Life Cycle

The entire lifetime of a service happens between the time onCreate() is called and the time onDestroy() returns. Toàn bộ cuộc đời của một service bắt đầu khi onCreate() được gọi và kết thúc khi onDestroy() trả về.

Like an activity, a service does its initial setup in onCreate(), and releases all remaining resources in onDestroy(). Cũng như một activity, một service thực hiện các công việc khởi tạo tại onCreate() và trả tất cả các tài nguyên còn lại tại OnDestroy()

For example, a music playback service could create the thread where the music will be played in onCreate(), and then stop the thread in onDestroy().Ví dụ, một service chơi nhạc có thể tạo thread phụ chơi nhạc tại phương thức onCreate(), và dừng thread đó tại onDestroy()

Page 6: Android chapter22-services

666

22. Android Services

Services

6

Broadcast Receiver LifecycleA Broadcast Receiver là lớp ứng dụng nghe các global Intent được gửi cho tất cả những ai muốn nghe (thay vì chỉ gửi cho một ứng dụng/activity được chỉ định trước).

Hệ thống gửi một broadcast Intent cho tất cả các broadcast receiver quan tâm, và chúng lần lượt xử lý Intent đó.

Page 7: Android chapter22-services

777

22. Android Services

Services

7

Registering a Broadcast Receiver

• Ta có thể đăng ký động (tại mã chương trình) một thực thể BroadcastReceiver bằng lời gọi Context.registerReceiver()

• hoặc đăng kí tĩnh bằng cách khai báo thẻ <receiver> tại AndroidManifest.xml.

Page 8: Android chapter22-services

888

22. Android Services

Services

8

Broadcast Receiver Lifecycle

Mỗi broadcast receiver có đúng một callback method:

void onReceive (Context context, Intent broadcastMsg)

1. Khi một broadcast message được gửi đến receiver, Android gọi phương thức onReceive() của receiver đó và truyền cho nó đối tượng Intent chứa message.

2. Một broadcast receiver chỉ được coi là active (đang chạy) trong khi nó đang thực thi phương onReceive() của mình.

3. Khi onReceive() kết thúc, receiver quay lại trạng thái inactive.

* callback method là các phương thức dành riêng để hệ thống gọi khi có sự kiện nào đó xảy ra, nó không được gọi trực tiếp trong mã chương trình.

onReceive

Page 9: Android chapter22-services

999

22. Android Services

Services

9

Services, BroadcastReceivers and the AndroidManifest

Manifest của các ứng dụng dùng Android Services phải có chứa:

1.Một <service> entry (mục) cho mỗi service dùng trong ứng dụng.

2.Nếu ứng dụng định nghĩa một BroadcastReceiver dưới hình thức một lớp độc lập, manifest phải có một <receiver> clause (mệnh đề) xác định component đó. Ngoài ra, còn cần một <intent-filter> entry để khai báo filter mà service và receiver sử dụng.

See example

Page 10: Android chapter22-services

101010

22. Android Services

Services

10

Services, BroadcastReceivers and the AdroidManifest<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cis493.demos" android:versionCode="1" android:versionName="1.0.0"> <uses-sdk android:minSdkVersion="4"></uses-sdk> <application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name=".MyServiceDriver2"> <intent-filter>

<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="MyService2" /> <receiver android:name="MyBroadcastReceiver"> <intent-filter> <action android:name = "matos.action.GOSERVICE2" /> </intent-filter> </receiver> </application></manifest>

Page 11: Android chapter22-services

111111

22. Android Services

Services

11

Types of Broadcasts

Có hai lớp broadcast chính:

1.Normal broadcast (được gửi bằng Context.sendBroadcast) hoàn toàn không đồng bộ (asynchronous). Tất cả các receiver của broadcast được chạy theo thứ tự không xác định, thường là chạy cùng lúc.

2.Ordered broadcast (được gửi bằng Context.sendOrderedBroadcast) được gửi lần lượt đến cho từng receiver một. Khi đến lượt một receiver thực thi, nó có thể chuyển tiếp kết quả cho receiver tiếp theo, hoặc nó có thể hủy toàn bộ broadcast (abortBroadcast()) để broadcast đó sẽ không được gửi đến cho các receiver khác. Thứ tự thực thi của các receiver được kiểm soát bởi thuộc tính android:priority của intent-filter tương ứng; các receiver có cùng priority (độ ưu tiên) sẽ được chạy theo thứ tự bất kì.

Page 12: Android chapter22-services

121212

22. Android Services

Services

12

Useful Methods – The DriverGiả sử main activity MyService3Driver muốn tương tác với một service có tên MyService3. Activity chính có trách nhiệm thực hiện các việc sau:

1. Start the service called MyService3. Bật service

Intent intentMyService = new Intent(this, MyService3.class);

Service myService = startService(intentMyService); 2. Define corresponding receiver’s filter and register local receiver. Định nghĩa filter của receiver tương ứng và đăng ký receiver nội bộ.

IntentFilter mainFilter = new IntentFilter("matos.action.GOSERVICE3");

BroadcastReceiver receiver = new MyMainLocalReceiver();registerReceiver(receiver, mainFilter);

3. Implement local receiver and override its main method

public void onReceive(Context localContext, Intent callerIntent)

Page 13: Android chapter22-services

131313

22. Android Services

Services

13

Useful Methods – The ServiceGiả sử main activity MyService3Driver muốn tương tác với một service có tên MyService3. Activity đó dùng phương thức onStart của nó để làm việc sau:

1. Tạo một Intent với broadcast filter phù hợp (bao nhiêu receiver khớp với nó cũng được).

Intent myFilteredResponse = new Intent("matos.action.GOSERVICE3");

2. Chuẩn bị dữ liệu extra (‘myServiceData’) để gửi theo intent tới (các) receiver

Object msg = some user data goes here;myFilteredResponse.putExtra("myServiceData", msg);

3. Gửi intent tới tất cả các receiver khớp với filter đã tạo

sendBroadcast(myFilteredResponse);

Page 14: Android chapter22-services

141414

22. Android Services

Services

14

Useful Methods – The Driver (again)Giả sử main activity MyService3Driver muốn tương tác với một service có tên MyService3. Activity chính có trách nhiệm kết thúc service một cách sạch sẽ. Thực hiện như sau

1. Giả sử intentMyService là Intent đã được dùng để gọi service. Việc kết thúc service được làm bằng cách gọi phương thức

stopService(new Intent(intentMyService) );

2. Tại phương thức onDestroy của activity, đảm bảo rằng tất cả các thread đang chạy của nó được chấm dứt và receiver được hủy đăng ký.

unregisterReceiver(receiver);

Page 15: Android chapter22-services

151515

22. Android Services

Example 1. A very Simple Service

15

Main activity bật một service. Service đó in vài dòng tại DDMS LogCat cho đến khi main activity dừng service. Không có liên lạc giữa các tiến trình khác nhau (IPC).

// a simple service is started & stoppedpackage es.demo;

import android.app.Activity;import android.os.Bundle;import android.content.ComponentName;import android.content.Intent;import android.view.View;import android.view.View.OnClickListener;import android.widget.*;

public class ServiceDriver1 extends Activity { TextView txtMsg; Button btnStopService; Intent intentMyService; ComponentName service;

Page 16: Android chapter22-services

161616

22. Android Services

Services

16

Example 1. cont.

@Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); txtMsg = (TextView) findViewById(R.id.txtMsg); intentMyService = new Intent(this, MyService1.class); service = startService(intentMyService); btnStopService = (Button) findViewById(R.id.btnStopService); btnStopService.setOnClickListener(new OnClickListener() { public void onClick(View v) { try { stopService((intentMyService) ); txtMsg.setText("After stoping Service: \n" + service.getClassName()); } catch (Exception e) { Toast.makeText(getApplicationContext(), e.getMessage(), 1).show(); } }//onClick });}}

Page 17: Android chapter22-services

171717

22. Android Services

Example 1. cont.

17

//non CPU intensive service running the main task in its main threadpackage es.demo;

import ...

public class MyService1 extends Service {

@Overridepublic IBinder onBind(Intent arg0) {

return null;}@Overridepublic void onCreate() {

super.onCreate();Log.i ("<<MyService1-onStart>>", "I am alive-1!");

}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {

super.onStartCommand(intent, flags, startId); Log.i ("<<MyService1-onStart>>", "I did something very

quickly");return START_STICKY;

}@Overridepublic void onDestroy() {

super.onDestroy();Log.i ("<<MyService1-onDestroy>>", "I am dead-1");

}}

Page 18: Android chapter22-services

181818

22. Android Services

Services

18

Example 1. cont.

According to the Log

1. Main Activity is started (no displayed yet)2. Service is started (onCreate, onStart)3. Main Activity UI is displayed4. User stops Service

Page 19: Android chapter22-services

191919

22. Android Services

Services

19

Example 1. cont. Manifest<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="es.demo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" />

<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".ServiceDriver1" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService1"> </service> </application></manifest>

Page 20: Android chapter22-services

202020

22. Android Services

Services

20

Example 1. cont. Layout

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

android:id="@+id/myLinearLayout"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"xmlns:android="http://schemas.android.com/apk/res/android" >

<EditTextandroid:id="@+id/txtMsg"android:layout_width="fill_parent"android:layout_height="wrap_content"android:textSize="18sp" />

<Buttonandroid:id="@+id/btnStopService"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=" Stop Service“ />

</LinearLayout>

Page 21: Android chapter22-services

212121

22. Android Services

Example 2

21

Example 2. A More Realistic Activity-Service Interaction

1. The main activity starts the service and registers a receiver. Activity chính bật service và đăng kí một receiver.

2. The service is slow, therefore it runs in a parallel thread its time consuming task. Service chạy chậm, nên nó chạy công việc của nó trong một thread song song.

3. When done with a computing cycle, the service adds a message to an intent. Sau mỗi chu kì tính toán, service gắn một message vào một intent

4. The intent is broadcasted using the filter: matos.action.GOSERVICE3. Intent được broadcast bằng filter matos.action.GOSERVICE3

5. A BroadcastReceiver (defined inside the main Activity) uses the previous filter and catches the message (displays the contents on the main UI ). Receiver (đã được đăng kí từ trong activity chính) dùng filter để bắt message mà service gửi rồi hiển thị tại UI.

6. At some point the main activity stops the service and finishes executing. Tại một thời điểm nào đó, activity chính dừng service và kết thúc.

Page 22: Android chapter22-services

222222

22. Android Services

Services

22

Example 2. Layout<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/myLinearLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" >

<EditText android:id="@+id/txtMsg" android:layout_width="fill_parent" android:layout_height="144dp" android:textSize="12sp" />

<Button android:id="@+id/btnStopService" android:layout_width="151dp" android:layout_height="wrap_content" android:text="Stop Service" />

</LinearLayout>

Page 23: Android chapter22-services

232323

22. Android Services

Services

23

Example 2. Manifest<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="es.demo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" />

<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".MyServiceDriver3" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="MyService3" /> </application></manifest>

Page 24: Android chapter22-services

242424

22. Android Services

Services

24

// Application logic and its BroadcastReceiver in the same classpackage es.demos;import java.util.Date;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Bundle;import android.os.SystemClock;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.*;

public class MyServiceDriver3 extends Activity { TextView txtMsg; Button btnStopService; ComponentName service; Intent intentMyService; BroadcastReceiver receiver;

Example 2. Main Activity

Page 25: Android chapter22-services

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); txtMsg = (TextView) findViewById(R.id.txtMsg); intentMyService = new Intent(this, MyService3.class); service = startService(intentMyService); txtMsg.setText("MyService3 started - (see DDMS Log)"); btnStopService = (Button) findViewById(R.id.btnStopService); btnStopService.setOnClickListener(new OnClickListener() {

public void onClick(View v) {try {

stopService(new Intent(intentMyService) );

txtMsg.setText("After stoping Service: \n" + service.getClassName());

} catch (Exception e) {e.printStackTrace();

} } });

252525

22. Android Services

Services

25

Example 2. Main Activity

stop

start

Page 26: Android chapter22-services

262626

22. Android Services

Services

26

// register & define filter for local listener IntentFilter mainFilter = new IntentFilter("es.action.GOSERVICE3");

receiver = new MyMainLocalReceiver();registerReceiver(receiver, mainFilter);

}//onCreate //////////////////////////////////////////////////////////////////////// @Override protected void onDestroy() {

super.onDestroy();try {

stopService(intentMyService);unregisterReceiver(receiver);

} catch (Exception e) {Log.e ("MAIN3-DESTROY>>>", e.getMessage() );

}Log.e ("MAIN3-DESTROY>>>" , "Adios" ); } //onDestroy

Example 2. Main Activity

register

unregister

Page 27: Android chapter22-services

272727

22. Android Services

Services

27

//////////////////////////////////////////////////////////////////////// local (embedded) RECEIVER

public class MyMainLocalReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context localContext, Intent callerIntent) {

String serviceData = callerIntent.getStringExtra("serviceData");

Log.e ("MAIN>>>", serviceData + " -receiving data " + SystemClock.elapsedRealtime() );

String now = "\n" + serviceData + " --- " + new Date().toLocaleString();txtMsg.append(now);

}

}//MyMainLocalReceiver

}//MyServiceDriver3

Example 2. Main Activity

Get data

Page 28: Android chapter22-services

282828

22. Android Services

Example 2. The Service

28

// Service3 uses a thread to run slow operationpackage es.demos;

import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.util.Log;

public class MyService3 extends Service { boolean isRunning = true;

@Overridepublic IBinder onBind(Intent arg0) {

return null;}

@Overridepublic void onCreate() {

super.onCreate();}

Page 29: Android chapter22-services

292929

22. Android Services

Example 2. The Service

29

@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {

super.onStartCommand(intent, flags, startId);Log.e ("<<MyService3-onStart>>", "I am alive-3!");// we place the slow work of the service in its own thread // so the caller is not hung up waiting for usThread triggerService = new Thread ( new Runnable(){

long startingTime = System.currentTimeMillis();long tics = 0;public void run() {

for(int i=0; (i< 120) & isRunning; i++) { //at most 10 minutestry { //fake that you are very busy here tics = System.currentTimeMillis() - startingTime; Intent myFilteredResponse = new Intent("es.action.GOSERVICE3"); String msg = i + " value: " + tics; myFilteredResponse.putExtra("serviceData", msg); sendBroadcast(myFilteredResponse); Thread.sleep(1000); //five seconds} catch (Exception e) { e.printStackTrace(); }

}//for}//run

});triggerService.start();return START_STICKY;}//onStartCommand

broadcasting

Set filter

Page 30: Android chapter22-services

303030

22. Android Services

Services

30

@Override public void onDestroy() {

super.onDestroy();Log.e ("<<MyService3-onDestroy>>", "I am dead-3");

isRunning = false;

}//onDestroy

}//MyService3

Example 2. The Service

Thread is now stopped

Page 31: Android chapter22-services

3131

22. Android Services

Services

31

Questions