一个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、使用步骤
  a、继承service类(位于android.app包下,一般用它的子类IntentService)

  b、AndroidManifast.xml配置清单文件中<application>节点里对服务进行配置

    <service name=".SMSService"/>
  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主要代码:

 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主要代码:

 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服务:

 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(),否则会报异常:

java.lang.IllegalArgumentException: Service not registered

最后别忘了AndroidManifast.xml里声明服务:

        <service android:enabled="true" android:name=".MyService" />
<service android:enabled="true" android:name=".MyBindService" />

依次点击四个按钮打印的日志:

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广播接收器放在下一篇介绍吧!

android学习日记19--四大组件之Services(服务)的更多相关文章

  1. android学习日记20--连接组件之Intent和IntentFilter

    上次刚了解完Android的四大组件,现在学习组件间通信的Intent和IntentFilter 一.Intent 1.简述 Intent(意图)在应用程序运行时连接两个不同组件,是一种运行时的绑定机 ...

  2. android学习日记19--四大组件之BroadcastReciver(广播接收者)

    二.BroadcastReciver(广播接收者) 1.简述 BroadcastReciver位于android.content包下,主要用于对广播消息(Intent)的过滤并响应的控件.可以理解为全 ...

  3. android学习日记05--Activity间的跳转Intent实现

    Activity间的跳转 Android中的Activity就是Android应用与用户的接口,所以了解Activity间的跳转还是必要的.在 Android 中,不同的 Activity 实例可能运 ...

  4. android学习日记03--常用控件Dialog

    常用控件 9.Dialog 我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框 对话框,要创建对话框之前首先要创建Bui ...

  5. android学习日记03--常用控件button/imagebutton

    常用控件 控件是对数据和方法的封装.控件可以有自己的属性和方法.属性是控件数据的简单访问者.方法则是控件的一些简单而可见的功能.所有控件都是继承View类 介绍android原生提供几种常用的控件bu ...

  6. android学习日记03--常用控件checkbox/radiobutton

    常用控件3.checkbox 复选框,确定是否勾选,点击一下勾选,点击第二下取消,当有一系列备选项时适合用checkbox控件,方便用户提交数据. 贴上例子Activity的java代码 packag ...

  7. Java乔晓松-android的四大组件之一Service(服务的绑定)

    android的四大组件之一Service(服务的绑定) 怎么绑定服务,又怎么解除服务,代码如下: MainActivity.java源码: package com.example.lesson14_ ...

  8. 【转】 Pro Android学习笔记(七六):服务(1):local和remote

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Android提供服务,服务是运行在后台的 ...

  9. 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件

    目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...

随机推荐

  1. windows官方多语言方案

    编写 Win32 多语言用户界面应用程序 Windows 2000 针对全球市场制定了新的增强支持标准,提供了许多国际化功能,例如完全支持 Unicode.预设支持数百种语言以及用于从右向左语言的镜像 ...

  2. 禅道,然之和蝉知入驻VM Depot

    Posted on 四月 21, 2015 by 陈阳 近日, 易软天创与微软开放技术合作,在虚拟镜像中国站点vmdepot.msopentech.cn上成功部署易软天创的集成管理环境,为希望快速基于 ...

  3. jquery通过ajax获取数据(优化、封装)

    下载页面查看: makeGrid.js   ,column.js  ,XiangMuGuanLi.aspx <div class="tb_container" id=&quo ...

  4. InstallShield高级应用--检查是否安装ORACLE或SQL Server

    InstallShield高级应用--检查是否安装ORACLE或SQL Server   实现原理:判断是否存在,是通过查找注册表是否含有相应标识来判断的. 注意:XP与WIN7系统注册表保存方式不一 ...

  5. ubuntu下eclipse打开win下的代码中文出现乱码

    问题出现的原因:因为windows下默认的编码是GBK,在ubuntu下是UTF-8所以,所以在windows下的注释,在ubuntu下就变成了乱码. 解决的方案: 1)  eclipse->w ...

  6. unix network programming(3rd)Vol.1 [第2~5章]《读书笔记系列》

    13~22章 重要 第2章 传输层: TCP/ UDP / STCP (Stream Control Transmission Protocol) TCP 可靠,有重传机制,SYN队列号 UDP 不可 ...

  7. spring的三种注入方式

    接口注入(不推荐) 构造器注入(死的应用) getter,setter方式注入(比较常用) Type1 接口注入 我们常常借助接口来将调用者与实现者分离.如: public class ClassA  ...

  8. Hadoop2.7.2安装笔记

    1.设置免密SSH登录 $ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa $ cat ~/.ssh/id_dsa.pub >> ~/.ssh/autho ...

  9. MapReduce自定义二次排序流程

    每一条记录开始是进入到map函数进行处理,处理完了之后立马就入自定义分区函数中对其进行分区,当所有输入数据经过map函数和分区函数处理完之后,就调用自定义二次排序函数对其进行排序. MapReduce ...

  10. 流(stream)

    流的概念 Java程序通过流来完成输入/输出.流是生产或消费信息的抽象.流通过Java的输入/输出系统与物理设备链接.尽管与它们链接的物理设备不尽相同,所有流的行为具有同样的方式.这样,相同的输入/输 ...