【原文:http://blog.csdn.net/corder_raine/article/details/8310126】
目录
第六天.Android Service
6.1Service概述
6.1.1 Service概念及用途
服务是运行在后台的一段代码。
不是进程,也不是线程。
可以运行在它自己的进程,也可以运行在其他应用程序进程的上下文(context)里面,这取决于自身的需要。
Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序。
媒体播放器的服务,当用户退出媒体选择用户界面,仍然希望音乐依然可以继续播放,这就是由服务(service)来保证当用户界面关闭时音乐继续播放的。
比如当我们一个应用的数据是通过网络获取的,不同时间的数据是不同的,这时候我们可以用Service在后台定时更新,而不用每打开应用的时候在去获取。
6.2 Service生命周期
onCreate()
在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onStart()
只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。
onDestroy()
服务被终止时调用。
onBind()
只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。
onUnbind()
只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。
startService后,即使调用startService的进程结束了Service仍然还存在,直到有进程调用stopService,或者Service自己自杀(stopSelf())。
bindService后,Service就和调用bindService的进程同生共死了,也就是说当调用bindService的进程死了,那么它bind的Service也要跟着被结束,当然期间也可以调用unbindservice让Service结束。
两种方式混合使用时,比如说你startService了,我bindService了,那么只有你stopService了而且我也unbindservice了,这个Service才会被结束。
6.3启动与停止Service
6.3.1 Service开发步骤
第一步:继承Service类
1
2
|
public
class
MyService
extends
Service {
}
|
第二步:在AndroidManifest.xml文件中的节点里对服务进行配置:
服务不能自己运行,使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
如果打算采用
Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
如果打算采用
Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。
6.3.2 采用startService()启动服务
采用Context.startService()方法启动服务的代码如下:
01
02
03
04
05
06
07
08
09
10
11
12
|
public
class
HelloActivity
extends
Activity {
public
void
onCreate(Bundle savedInstanceState) {
......
Button button =(Button)
this
.findViewById(R.id.button);
button.setOnClickListener(
new
View.OnClickListener(){
public
void
onClick(View v) {
Intent intent =
new
Intent(HelloActivity.
this
, SMSService.
class
);
startService(intent);
}});
}
}
|
6.3.3 采用bindService()启动服务
采用Context.startService()方法启动服务的代码如下:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
public
class
HelloActivity
extends
Activity {
ServiceConnection conn =
new
ServiceConnection() {
public
void
onServiceConnected(ComponentName name, IBinder service) {
}
public
void
onServiceDisconnected(ComponentName name) {
}
};
public
void
onCreate(Bundle savedInstanceState) {
Button button =(Button)
this
.findViewById(R.id.button);
button.setOnClickListener(
new
View.OnClickListener(){
public
void
onClick(View v) {
Intent intent =
new
Intent(HelloActivity.
this
, SMSService.
class
);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
//unbindService(conn);//解除绑定
}});
}
}
|
6.3.4 Service服务演示
1.新建一个Android工程ServiceDemo
2.修改main.xml代码,增加二个按钮
3.新建一个Service,命名为MyService.java
4.新建ServiceDemo.java
5.配置AndroidManifest.xml
6.执行上述工程, 用Logcat查看日志
7.按HOME键进入Settings(设置)à
Applications(应用)à
RunningServices(正在运行的服务)
main.xml
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
android:orientation
=
"vertical"
android:layout_width
=
"fill_parent"
android:layout_height
=
"fill_parent"
>
<
TextView
android:id
=
"@+id/text"
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:text
=
"@string/hello"
/>
<
Button
android:id
=
"@+id/startservice"
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:text
=
"startService"
/>
<
Button
android:id
=
"@+id/stopservice"
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:text
=
"stopService"
/>
</
LinearLayout
>
|
MyService.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
public
class
MyService
extends
Service {
//定义个一个Tag标签
private
static
final
String TAG =
"MyService"
;
//一个Binder类,用在onBind() 方法里,这样Activity那边可以获取到
private
MyBinder mBinder =
new
MyBinder();
public
IBinder onBind(Intent intent) {
Log.e(TAG,
"start IBinder~~~"
);
return
mBinder;
}
public
void
onCreate() {
Log.e(TAG,
"start onCreate~~~"
);
super
.onCreate();
}
public
void
onStart(Intent intent,
int
startId) {
Log.e(TAG,
"start onStart~~~"
);
super
.onStart(intent, startId);
}
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
public
void
onDestroy() {
Log.e(TAG,
"start onDestroy~~~"
);
super
.onDestroy();
}
public
boolean
onUnbind(Intent intent) {
Log.e(TAG,
"start onUnbind~~~"
);
return
super
.onUnbind(intent);
}
public
String getSystemTime(){
Time t =
new
Time();
t.setToNow();
return
t.toString();
}
public
class
MyBinder
extends
Binder{
MyService getService()
{
return
MyService.
this
;
}
} }
|
ServiceDemo.java
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public
class
ServiceDemo
extends
Activity
implements
OnClickListener {
private
MyService mMyService;
private
TextView mTextView;
private
Button startServiceButton;
private
Button stopServiceButton;
private
Context mContext;
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
setupViews();
}
|
01
02
03
04
05
06
07
08
09
10
11
|
public
void
setupViews(){
mContext = ServiceDemo.
this
;
mTextView = (TextView)findViewById(R.id.text);
startServiceButton = (Button)findViewById(R.id.startservice);
stopServiceButton = (Button)findViewById(R.id.stopservice);
startServiceButton.setOnClickListener(
this
);
stopServiceButton.setOnClickListener(
this
);
}
|
01
02
03
04
05
06
07
08
09
10
11
12
|
public
void
onClick(View v) {
if
(v == startServiceButton){
Intent i =
new
Intent();
i.setClass(ServiceDemo.
this
, MyService.
class
);
mContext.startService(i);
}
else
if
(v == stopServiceButton){
Intent i =
new
Intent();
i.setClass(ServiceDemo.
this
, MyService.
class
);
mContext.stopService(i);
}
}
}
|
AndroidManifest.xml
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
package
=
"com.lxt008"
android:versionCode
=
"1"
android:versionName
=
"1.0"
>
<
application
android:icon
=
"@drawable/icon"
android:label
=
"@string/app_name"
>
<
activity
android:name
=
".ServiceDemo"
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
=
".MyService"
android:exported
=
"true"
></
service
>
</
application
>
<
uses-sdk
android:minSdkVersion
=
"7"
/>
</
manifest
>
|
6.4Notification通知
如果需要查看消息,可以拖动状态栏到屏幕下方即可查看消息。
发送消息的代码如下:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
//获取通知管理器
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int
icon = android.R.drawable.stat_notify_chat;
long
when = System.currentTimeMillis();
//新建一个通知,指定其图标和标题
//第一个参数为图标,第二个参数为标题,第三个为通知时间
Notification notification =
new
Notification(icon,
null
, when);
Intent openintent =
new
Intent(
this
, OtherActivity.
class
);
//当点击消息时就会向系统发送openintent意图
PendingIntent contentIntent = PendingIntent.getActivity(
this
,
0
, openintent,
0
);
notification.setLatestEventInfo(
this
, “标题”, “我是内容", contentIntent);
mNotificationManager.notify(
0
, notification);
|
6.4.1 Android中的通知(Notification)
6.5案例分析
参考案例:NotificationDemo
7个demo以打包
包括
ch08_serviceactivity
ch08_servicelifecycle
ch08_thread
ch08_timer
NotificationDemo
ServiceActivity
ServiceDemo
源代码下载