一个Android应用主要由四个基本组件组成,Android四大基本组件分别是Activity,Content Provider内容提供者,Service服务,BroadcastReceiver广播接收器。其中Activity和Content Provider在前面都有介绍过。这里主要讲讲Service服务和BroadcastReceiver广播接收器。
一、Services(服务)
1、简述
Services(服务)简单来说就是剥夺界面的Activity。它和Activity很多概念都是相似的,都是封装有一个完整的功能逻辑实现。
Services是运行在后台的一段代码,它可以运行在它自己的进程,也可以运行在其他应用程序进程的上下文(context)里面,
其它的组件可以绑定到一个服务(Service)上面,通过远程过程调用(RPC)来调用这个方法。常见的Services如后台音乐播放,
后台计算数据。
2、运行原理
有两种运行方式,原理如下:
a、使用Context.startService()来启动一个Service,从而可以在后台调用Service。同时,系统也将保持这个Service一直执行,
直到这个Service运行结束。
b、使用Context.bindService()方法,连接到一个Service上(如果这个Service还没有运行将启动它)。当连接到一个Service之后,
我们还可以Service提供的接口与它进行通讯。
3、生命周期
官方生命周期的图示:
a、startService后,即使调用startService的进程结束了,Service仍然还存在,直到有进程调用stopService,或者Service自己自杀(stopSelf())。
b、bindService后,Service就和调用bindService的进程同生共死了,也就是说当调用bindService的进程死了,那么它bind的Service也要跟着被结束,
当然期间也可以调用unbindservice让 Service结束。
c、两种方式混合使用时,比如说你startService了,我bindService了,那么只有你stopService了而且我也unbindservice了,这个Service才会被结束。
4、使用步骤
- c、服务不能自己运行,需要通过Contex.startService()或Contex.bindService()启动服务
通过startService()方法启动的服务于调用者没有关系,即使调用者关闭了,服务仍然运行想停止服务要调用Context.stopService(),
此时系统会调用onDestory(),使用此方法启动时,服务首次启动系统先调用服务的onCreate()–>onStart(),如果服务已经启动再次调用只会触发onStart()方法
使用bindService()启动的服务与调用者绑定,只要调用者关闭服务就终止,使用此方法启动时,服务首次启动系统先调用服务的onCreate()–>onBind(),
如果服务已经启动再次调用不会再触发这2个方法,调用者退出时系统会调用服务的onUnbind()–>onDestory(),想主动解除绑定可使用Contex.unbindService(),
系统依次调用onUnbind()–>onDestory();
区别使用 startService()还是bindService()就要看是否要和调用者进行通信,由于startService()和访问者不存在太多联系,所有有进行通信的要用bindService()。
通过Service提供IBinder OnBind(Intent intent) 返回要通信的数据,在OnServiceConnected()方法 返回该Binder给调用者。
5、运行实例
运用两种启动Service服务写个后台播放音乐的例子
MyServices主要代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
private static final String TAG = "MyService" ;
MediaPlayer player ;
@Override
public IBinder onBind ( Intent intent ) {
return null ;
}
@Override
public void onCreate () {
Toast . makeText ( this , "My Service Created" , Toast . LENGTH_LONG ). show ();
Log . v ( TAG , "onCreate" );
player = MediaPlayer . create ( this , R . raw . ten_year ); //运行例子是,需要替换具体音乐的名称
player . setLooping ( false ); // Set looping
}
@Override
public void onDestroy () {
Toast . makeText ( this , "My Service Stopped" , Toast . LENGTH_LONG ). show ();
Log . v ( TAG , "onDestroy" );
player . stop ();
}
@Override
public void onStart ( Intent intent , int startid ) {
Toast . makeText ( this , "My Service Started" , Toast . LENGTH_LONG ). show ();
Log . v ( TAG , "onStart" );
player . start ();
}
MyBindService主要代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private static final String TAG = "MyBindService" ;
MediaPlayer player = null ;
MyBinder mybinder = new MyBinder ();
class MyBinder extends Binder { //需要新建个内部的Binder类
public MyBindService getService (){
return MyBindService . this ;
}
}
@Override
public IBinder onBind ( Intent intent ) {
return mybinder ;
}
@Override
public void onCreate () {
Toast . makeText ( this , "My Service Created" , Toast . LENGTH_LONG ). show ();
Log . v ( TAG , "onCreate" );
player = MediaPlayer . create ( this , R . raw . ten_year ); //运行例子是,需要替换音乐的名称
player . setLooping ( false ); // Set looping
}
public void playMusic () {
player . start ();
Log . v ( TAG , "playMusic" );
}
@Override
public void onDestroy () {
Toast . makeText ( this , "My Service Stopped" , Toast . LENGTH_LONG ). show ();
Log . v ( TAG , "onDestroy" );
player . stop ();
}
@Override
public void onStart ( Intent intent , int startid ) {
Toast . makeText ( this , "My Service Started" , Toast . LENGTH_LONG ). show ();
Log . v ( TAG , "onStart" );
}
Activity注册按钮事件,调用Service服务:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
ServiceConnection conn = new ServiceConnection () {
@Override
public void onServiceDisconnected ( ComponentName arg0 ) {
// TODO Auto-generated method stub
}
@Override
public void onServiceConnected ( ComponentName arg0 , IBinder binder ) {
// TODO Auto-generated method stub
MyBinder mBinder = ( MyBinder ) binder ;
MyBindService mService = mBinder . getService (); //取到自己的Service
mService . playMusic (); // 调用服务要执行的方法
}
};
public void onClick ( View src ) {
switch ( src . getId ()) {
case R . id . btn_start :
Log . v ( TAG , "onClick: start srvice" );
startService ( new Intent ( this , MyService . class ));
break ;
case R . id . btn_stop :
Log . v ( TAG , "onClick: stop srvice" );
stopService ( new Intent ( this , MyService . class ));
break ;
case R . id . btn_bind :
Log . v ( TAG , "onClick: bind srvice" );
bindService ( new Intent ( MainActivity . this , MyBindService . class ), conn , BIND_AUTO_CREATE );
break ;
case R . id . btn_unbind :
if ( true ) {
Log . v ( TAG , "onClick: unbind srvice" );
unbindService ( conn );
flag = false ;
}
break ;
}
}
注意:unbind()调用是要进行判断,没bind()后不能多次调用unbind(),否则会报异常:
1
java . lang . IllegalArgumentException : Service not registered
最后别忘了AndroidManifast.xml里声明服务:
1
2
<service android:enabled= "true" android:name= ".MyService" />
<service android:enabled= "true" android:name= ".MyBindService" />
依次点击四个按钮打印的日志:
1
2
3
4
5
6
7
8
9
03-22 07:19:44.116: V/ServicesDemo(18347): onClick: start srvice
03-22 07:19:44.166: V/MyService(18347): onStart
03-22 07:19:48.807: V/ServicesDemo(18347): onClick: stop srvice
03-22 07:19:48.837: V/MyService(18347): onDestroy
03-22 07:19:50.957: V/ServicesDemo(18347): onClick: bind srvice
03-22 07:19:50.997: V/MyBindService(18347): onCreate
03-22 07:19:51.067: V/MyBindService(18347): playMusic
03-22 07:19:55.997: V/ServicesDemo(18347): onClick: unbind srvice
03-22 07:19:56.097: V/MyBindService(18347): onDestroy
这里可以同时start srvice和bind srvice,这时就有两个相同的服务,根据调用的不同时间,播放不同进度的音乐。
调用系统服务getSystemService是Activity中的方法,根据传入的name来取得对应的服务对象,这些服务名称参数都是Context类中的常量:
传入的Name 返回的对象 说明
WINDOW_SERVICE WindowManager 管理打开的窗口程序
LAYOUT_INFLATER_SERVICE LayoutInflater 取得xml里定义的view
ACTIVITY_SERVICE ActivityManager 管理应用程序的系统状态
POWER_SERVICE PowerManger 电源的服务
ALARM_SERVICE AlarmManager 闹钟的服务
NOTIFICATION_SERVICE NotificationManager 状态栏的服务
KEYGUARD_SERVICE KeyguardManager 键盘锁的服务
LOCATION_SERVICE LocationManager 位置的服务,如GPS
SEARCH_SERVICE SearchManager 搜索的服务
VEBRATOR_SERVICE Vebrator 手机震动的服务
CONNECTIVITY_SERVICE Connectivity 网络连接的服务
WIFI_SERVICE WifiManager Wi-Fi服务
TELEPHONY_SERVICE TeleponyManager 电话服务
BroadcastReceiver广播接收器放在下一篇介绍吧!