Service 概述:
Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。
Service有两种状态,“启动的”和“绑定”
通过startService()启动的服务处于“启动的”状态,一旦启动,service就在后台运行,即使启动它的应用组件已经被销毁了。通常started状态的service执行单任务并且不返回任何结果给启动者。比如当下载或上传一个文件,当这项操作完成时,service应该停止它本身。
还有一种“绑定”状态的service,通过调用bindService()来启动,一个绑定的service提供一个允许组件与service交互的接口,可以发送请求、获取返回结果,还可以通过夸进程通信来交互(IPC)。绑定的service只有当应用组件绑定后才能运行,多个组件可以绑定一个service,当调用unbind()方法时,这个service就会被销毁了。
另外,在官方的说明文档中还有一个警告:
意思是service与activity一样都存在与当前进程的主线程中,所以,一些阻塞UI的操作,比如耗时操作不能放在service里进行,比如另外开启一个线程来处理诸如网络请求的耗时操作。如果在service里进行一些耗CPU和耗时操作,可能会引发Application Not Responding (ANR)警告,这时应用会弹出是强制关闭还是等待的对话框。所以,对service的理解就是和activity平级的,只不过是看不见的,在后台运行的一个组件,这也是为什么和activity同被说为Android的基本组件。
Service 的生命周期图:
下面给一个实例给大家看下 启动服务跟绑定服务的使用:
MainActivity的代码:
package com.example.servicedemo;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener,ServiceConnection{
private Button btnStartService,btnStopService;
private Button btnBindService,btnUnbindService,btnGetCurrentNum;
//创建一个Intent,启动服务
private Intent serviceIntent;
//创建一个自定义服务
private EchoService echoService=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWidget();
}
/**
* 初始化控件
*/
private void initWidget(){
//启动指定的服务
serviceIntent = new Intent(this,EchoService.class);
btnStartService = (Button) findViewById(R.id.btn_start_service);
btnStopService = (Button) findViewById(R.id.btn_stop_service);
btnBindService = (Button) findViewById(R.id.btn_bind_service);
btnUnbindService = (Button) findViewById(R.id.btn_unbind_service);
btnGetCurrentNum = (Button) findViewById(R.id.btn_get_current_num);
btnStartService.setOnClickListener(this);
btnStopService.setOnClickListener(this);
btnBindService.setOnClickListener(this);
btnUnbindService.setOnClickListener(this);
btnGetCurrentNum.setOnClickListener(this);
}
/**
* 监听事件
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start_service:
//启动服务
//Activity失去焦点后,服务还是一直在运行
startService(serviceIntent);
break;
case R.id.btn_stop_service:
//关闭服务
stopService(serviceIntent);
break;
case R.id.btn_bind_service:
//绑定服务
//Activity失去焦点后,服务停止运行。
//只有与服务进行绑定,才能进行通信。
bindService(serviceIntent, this, Context.BIND_AUTO_CREATE);//(intent,监听服务的状态,flags)
break;
case R.id.btn_unbind_service:
//取消绑定服务
if(echoService!=null){
unbindService(this);
echoService=null;
}
break;
case R.id.btn_get_current_num:
//获取绑定服务的当前数字
if(echoService!= null){
System.out.println("当前服务中的数字:"+echoService.getCurrentNum());
}
break;
}
}
/**
* 绑定服务
*/
//成功绑定服务后执行的方法
@Override
//IBinder 就是onBind的返回值
public void onServiceConnected(ComponentName name, IBinder binder) {
System.out.println("绑定服务成功");
//获取服务的实例
echoService = ((EchoService.EchoSerivceBinder)binder).getService();
}
//服务崩溃执行的方法
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
}
}
MainActivity的布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="@+id/btn_start_service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StartService" />
<Button
android:id="@+id/btn_stop_service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopService" />
<Button
android:id="@+id/btn_bind_service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BindService" />
<Button
android:id="@+id/btn_unbind_service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="UnbindService" />
<Button
android:id="@+id/btn_get_current_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="GetCurrentNum" />
</LinearLayout >
创建一个Service
备注:创建一个Service的时候必须在配置文件中声明一个Service
package com.example.servicedemo;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class EchoService extends Service{
private final EchoSerivceBinder echoServiceBinder = new EchoSerivceBinder();
private Timer timer=null;//定时器工具
private TimerTask task=null;//抽象类
private int i = 0;
/**
* 启动服务
*/
//创建Service实例(只会创建一次)
@Override
public void onCreate() {
System.out.println(">>>>>onCreate");
startTimer();
super.onCreate();
}
//销毁
@Override
public void onDestroy() {
System.out.println(">>>>>onDestroy");
stopTimer();
super.onDestroy();
}
/**
* 绑定服务
*/
//内部类(继承Binder)
public class EchoSerivceBinder extends Binder{
//取得服务实例
public EchoService getService(){
return EchoService.this;
}
}
//取得当前服务内部的数字
public int getCurrentNum(){
return i;
}
@Override
public IBinder onBind(Intent arg0) {
System.out.println(">>>>onBind");
return echoServiceBinder;//返回值与控件交互,才能成功绑定服务,null时,绑定服务失败
}
//启动定时器
public void startTimer(){
if(timer==null){
timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
// TimerTask 执行方法
i++;
System.out.println(i);
}
};
timer.schedule(task, 1000, 2000);//1000:延迟1秒执行,每2秒执行一次。
}
}
//停止定时器
public void stopTimer(){
if(timer != null){
task.cancel();
timer.cancel();
System.out.println("stopTimer");
//因为前面有判断timer 是否等于空
timer = null;
task = null;
}
}
}
请尊重个人劳动成果,转发+地址: