Transcript Services

22
Android
Services
Notes are based on:
Android Developers
http://developer.android.com/index.html
22. Android Services
Services
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().
2
22. Android Services
Services
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.
3
22. Android Services
Services
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
4
22. Android Services
Services
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()
5
22. Android Services
Services
Broadcast Receiver Lifecycle
A 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 đó.
6
22. Android Services
Services
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.
7
22. Android Services
Services
Broadcast Receiver Lifecycle
onReceive
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.
8
22. Android Services
Services
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
9
22. Android Services
Services
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>
10
22. Android Services
Services
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ì.
11
22. Android Services
Services
Useful Methods – The Driver
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 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)
12
22. Android Services
Services
Useful Methods – The Service
Giả 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);
13
22. Android Services
Services
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);
14
22. Android Services
Example 1. A very Simple Service
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 & stopped
package es.demo;
import
import
import
import
import
import
import
android.app.Activity;
android.os.Bundle;
android.content.ComponentName;
android.content.Intent;
android.view.View;
android.view.View.OnClickListener;
android.widget.*;
public class ServiceDriver1 extends Activity {
TextView txtMsg;
Button btnStopService;
Intent intentMyService;
ComponentName
service;
15
22. Android Services
Services
Example 1. cont.
@Override
public 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
});
}
}
16
22. Android Services
Example 1. cont.
//non CPU intensive service running the main task in its main thread
package es.demo;
import ...
public class MyService1 extends Service {
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.i ("<<MyService1-onStart>>", "I am alive-1!");
}
@Override
public 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;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i ("<<MyService1-onDestroy>>", "I am dead-1");
}
}
17
22. Android Services
Services
Example 1. cont.
According to the Log
1.
2.
3.
4.
Main Activity is started (no displayed yet)
Service is started (onCreate, onStart)
Main Activity UI is displayed
User stops Service
18
22. Android Services
Services
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>
19
22. Android Services
Services
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"
>
<EditText
android:id="@+id/txtMsg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
<Button
android:id="@+id/btnStopService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" Stop Service“
/>
</LinearLayout>
20
22. Android Services
Example 2
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.
21
22. Android Services
Services
Example 2. Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/ap
k/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>
22
22. Android Services
Services
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>
23
22. Android Services
Services
Example 2. Main Activity
// Application logic and its BroadcastReceiver in the same class
package 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;
24
22. Android Services
Services
Example 2. Main Activity
@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);
start
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) );
stop
txtMsg.setText("After stoping Service: \n" +
service.getClassName());
} catch (Exception e) {
e.printStackTrace();
}
}
});
25
22. Android Services
Services
Example 2. Main Activity
// register & define filter for local listener
IntentFilter mainFilter = new IntentFilter("es.action.GOSERVICE3");
receiver = new MyMainLocalReceiver();
register
registerReceiver(receiver, mainFilter);
}//onCreate
////////////////////////////////////////////////////////////////////////
@Override
protected void onDestroy() {
super.onDestroy();
try {
stopService(intentMyService);
unregisterReceiver(receiver);
unregister
} catch (Exception e) {
Log.e ("MAIN3-DESTROY>>>", e.getMessage() );
}
Log.e ("MAIN3-DESTROY>>>" , "Adios" );
} //onDestroy
26
22. Android Services
Services
Example 2. Main Activity
//////////////////////////////////////////////////////////////////////
// local (embedded) RECEIVER
public class MyMainLocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context localContext, Intent callerIntent) {
Get data
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
27
22. Android Services
Example 2. The Service
// Service3 uses a thread to run slow operation
package es.demos;
import
import
import
import
android.app.Service;
android.content.Intent;
android.os.IBinder;
android.util.Log;
public class MyService3 extends Service {
boolean isRunning = true;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
28
22. Android Services
Example 2. The Service
@Override
public 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 us
Thread 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 minutes
try {
//fake that you are very busy here
tics = System.currentTimeMillis() - startingTime;
Intent myFilteredResponse =
Set filter
new Intent("es.action.GOSERVICE3");
String msg = i + " value: " + tics;
myFilteredResponse.putExtra("serviceData", msg);
broadcasting
sendBroadcast(myFilteredResponse);
Thread.sleep(1000); //five seconds
} catch (Exception e) { e.printStackTrace(); }
}//for
}//run
});
triggerService.start();
return START_STICKY;
}//onStartCommand
29
22. Android Services
Services
Example 2. The Service
@Override
public void onDestroy() {
super.onDestroy();
Log.e ("<<MyService3-onDestroy>>", "I am dead-3");
isRunning = false;
Thread is now stopped
}//onDestroy
}//MyService3
30
22. Android Services
Services
Questions
31