Service

一、Service的概念
Service是Android程序中四大基础组件之一,它和Activity一样都是Context的子类,只不过它没有UI界面,是在后台运行的组件。

[img]http://dl.iteye.com/upload/attachment/446474/598c906f-6c58-3bab-803a-c4483ef9f96b.jpg[/img]

二、Service的生命周期
Service对象不能自己启动,需要通过某个Activity、Service或者其他Context对象来启动。启动的方法有两种,Context.startService和Context.bindService()。两种方式的生命周期是不同的,具体如下所示。
Context.startService方式的生命周期: 
启动时,startService –> onCreate() –> onStart() 
停止时,stopService –> onDestroy()
Context.bindService方式的生命周期: 
绑定时,bindService  -> onCreate() –> onBind() 
解绑定时,unbindService –>onUnbind() –> onDestory()
三、实例:控制音乐播放的Service
下面我们用一个可以控制在后台播放音乐的例子来演示刚才所学知识,同学们可以通过该例子可以明显看到通过绑定方式运行的Service在绑定对象被销毁后也被销毁了。

[img]http://dl.iteye.com/upload/attachment/446476/e16f5226-c47d-3d75-9fcf-f5fc68a9cf75.png[/img]

下面把代码分享如下:
1、建立一个新项目名字叫 Lesson14_HelloService,Activity起名叫MainHelloService.java
2、res/layout/main.xml中代码写成
01 < ?xml version="1.0" encoding="utf-8"?>
02 <linearlayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="fill_parent"android:layout_height="fill_parent">
03 <textview android:layout_width="fill_parent" android:layout_height="wrap_content"android:text="音乐播放服务" android:textsize="25sp" android:layout_margintop="10dp">
04 <button android:text="开启音乐播放服务" android:textsize="20sp"android:id="@+id/Button01" android:layout_width="wrap_content"android:layout_height="wrap_content" android:layout_margintop="10dp">
05 </button>
06 <button android:text="停止音乐播放服务" android:textsize="20sp"android:id="@+id/Button02" android:layout_width="wrap_content"android:layout_height="wrap_content" android:layout_margintop="10dp">
07 </button>
08
09 <button android:text="绑定音乐播放服务" android:textsize="20sp"android:id="@+id/Button03" android:layout_width="wrap_content"android:layout_height="wrap_content" android:layout_margintop="10dp">
10 </button>
11 <button android:text="解绑定音乐播放服务" android:textsize="20sp"android:id="@+id/Button04" android:layout_width="wrap_content"android:layout_height="wrap_content" android:layout_margintop="10dp">
12 </button>
13 </textview></linearlayout>

在AndroidManifest.xml中描述如下
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.basic.lesson14"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainHelloService"
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:enabled="true" android:name=".MusicService">
</service>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>


2、在res目录中建立一个raw目录,并把一个音乐文件babayetu.mp3拷贝进来
3、在Activity的同目录新建一个service文件MusicService.java
01 package android.basic.lesson14;
02
03 import android.app.Service;
04 import android.content.Intent;
05 import android.media.MediaPlayer;
06 import android.os.IBinder;
07 import android.util.Log;
08 import android.widget.Toast;
09
10 public class MusicService extends Service {
11
12     //为日志工具设置标签
13     String tag ="MusicService";
14
15     //定义音乐播放器变量
16     MediaPlayer mPlayer;
17
18     //其他对象通过bindService方法通知该Service时该方法会被调用
19     @Override
20     public IBinder onBind(Intent intent) {
21         Toast.makeText(this,"MusicService onBind()",Toast.LENGTH_SHORT).show();
22         Log.i(tag, "MusicService onBind()");
23         mPlayer.start();
24         return null;
25     }
26
27     //其他对象通过unbindService方法通知该Service时该方法会被调用
28     @Override
29     public boolean onUnbind(Intent intent){
30         Toast.makeText(this, "MusicService onUnbind()", Toast.LENGTH_SHORT).show();
31         Log.i(tag, "MusicService onUnbind()");
32         mPlayer.stop();
33         return false;
34     }
35
36     //该服务不存在需要被创建时被调用,不管startService()还是bindService()都会在启动时调用该方法
37     @Override
38     public void onCreate(){
39         Toast.makeText(this, "MusicService onCreate()", Toast.LENGTH_SHORT).show();
40         //创建一个音乐播放器对象
41         mPlayer=MediaPlayer.create(getApplicationContext(), R.raw.babayetu);
42         //设置可以重复播放
43         mPlayer.setLooping(true);
44         Log.i(tag, "MusicService onCreate()");
45     }
46
47     //用startService方法调用该服务时,在onCreate()方法调用之后,会调用改方法
48     @Override
49     public void onStart(Intent intent,int startid){
50         Toast.makeText(this,"MusicService onStart",Toast.LENGTH_SHORT).show();
51         Log.i(tag, "MusicService onStart()");
52         mPlayer.start();
53     }
54
55     //该服务被销毁时调用该方法
56     @Override
57     public void onDestroy(){
58         Toast.makeText(this, "MusicService onDestroy()", Toast.LENGTH_SHORT).show();
59         mPlayer.stop();
60         Log.i(tag, "MusicService onDestroy()");
61     }
62 }

4、MainHelloService.java中的代码:

01 package android.basic.lesson14;
02
03 import android.app.Activity;
04 import android.content.ComponentName;
05 import android.content.Context;
06 import android.content.Intent;
07 import android.content.ServiceConnection;
08 import android.os.Bundle;
09 import android.os.IBinder;
10 import android.util.Log;
11 import android.view.View;
12 import android.view.View.OnClickListener;
13 import android.widget.Button;
14 import android.widget.Toast;
15
16 public class MainHelloService extends Activity {
17
18     //为日志工具设置标签
19     String tag = "MusicService";
20
21     /** Called when the activity is first created. */
22     @Override
23     public void onCreate(Bundle savedInstanceState) {
24         super.onCreate(savedInstanceState);
25         setContentView(R.layout.main);
26
27         //输出Toast消息和日志记录
28         Toast.makeText(MainHelloService.this, "MainHelloService onCreate", Toast.LENGTH_SHORT).show();
29         Log.i(tag, "MainHelloService onCreate");
30
31         //定义组件对象
32         Button b1= (Button)findViewById(R.id.Button01);
33         Button b2= (Button)findViewById(R.id.Button02);
34         Button b3= (Button)findViewById(R.id.Button03);
35         Button b4= (Button)findViewById(R.id.Button04);
36
37          //定义服务链接对象
38          final ServiceConnection conn = new ServiceConnection(){
39
40             @Override
41             public void onServiceConnected(ComponentName name, IBinder service) {
42                 Toast.makeText(MainHelloService.this, "ServiceConnection onServiceConnected", Toast.LENGTH_SHORT).show();
43                 Log.i(tag, "ServiceConnection onServiceConnected");
44
45             }
46
47             @Override
48             public void onServiceDisconnected(ComponentName name) {
49                 Toast.makeText(MainHelloService.this, "ServiceConnection onServiceDisconnected", Toast.LENGTH_SHORT).show();
50                 Log.i(tag, "ServiceConnection onServiceDisconnected");
51
52             }};
53
54         //定义点击监听器
55         OnClickListener ocl= new OnClickListener(){
56
57             @Override
58             public void onClick(View v) {
59                 //显示指定intent所指的对象是个Service
60                 Intent intent = newIntent(MainHelloService.this,android.basic.lesson14.MusicService.class);
61                 switch(v.getId()){
62                 case R.id.Button01:
63                     //开始服务
64                     startService(intent);
65                     break;
66                 case R.id.Button02:
67                     //停止服务
68                     stopService(intent);
69                     break;
70                 case R.id.Button03:
71                     //绑定服务
72                     bindService(intent,conn,Context.BIND_AUTO_CREATE);
73                     break;
74                 case R.id.Button04:
75                     //解除绑定
76                     unbindService(conn);
77                     break;
78                 }
79             }
80         };
81
82         //绑定点击监听器
83         b1.setOnClickListener(ocl);
84         b2.setOnClickListener(ocl);
85         b3.setOnClickListener(ocl);
86         b4.setOnClickListener(ocl);   
87
88     }
89
90     @Override
91     public void onDestroy(){
92         super.onDestroy();
93         Toast.makeText(MainHelloService.this, "MainHelloService onDestroy", Toast.LENGTH_SHORT).show();
94         Log.i(tag, "MainHelloService onDestroy");
95     }
96 }
### Service的生命周期和状态 ServiceAndroid系统中可以分为两种主要状态:启动状态和绑定状态。当一个Service被启动后,它会在后台长时间运行,即使启动它的组件已经被销毁,Service仍然可以继续运行[^2]。如果一个Service既被启动又被绑定,那么它会同时处于这两种状态。 ### Service的生命周期方法 自定义的Service需要继承`Service`基类,并且通常需要重写一些生命周期方法来实现特定的功能: - `onCreate()`:当Service第一次创建时调用。如果Service已经存在,则不会调用此方法。 - `onStartCommand(Intent intent, int flags, int startId)`:当其他组件通过调用`startService()`方法请求启动Service时调用。在这个方法里可以处理长时间运行的操作。 - `onBind(Intent intent)`:当其他组件通过调用`bindService()`方法绑定到Service时调用。该方法返回一个`IBinder`接口,允许客户端与Service进行通信。 - `onUnbind(Intent intent)`:当所有绑定到Service的客户端都解绑后调用。 - `onDestroy()`:当Service不再使用并被销毁时调用。这是释放资源的好时机。 ### 启动状态下的Service 当一个Service通过调用`startService()`方法启动时,它进入启动状态。在这种状态下,Service独立于启动它的组件运行,直到它自己停止或被系统终止。要停止这样的Service,可以在Service内部调用`stopSelf()`方法,或者从外部组件调用`stopService()`方法[^1]。 ### 绑定状态下的Service 当组件通过调用`bindService()`方法绑定Service时,Service进入绑定状态。此时,组件可以通过`ServiceConnection`对象获取到Service提供的`IBinder`对象,从而与Service进行交互。绑定状态下的Service可以被多个组件绑定,只有当所有绑定的组件都解绑后,Service才会被销毁[^3]。 ### Service的声明 无论哪种类型的Service,都需要在`AndroidManifest.xml`文件中声明。声明格式如下: ```xml <service android:name=".Demo2Service" /> ``` 其中`.Demo2Service`是你的Service类名[^2]。 ### Service的绑定过程 为了与Service进行交互,组件需要创建一个`ServiceConnection`实例,并实现其`onServiceConnected()`和`onServiceDisconnected()`回调方法。例如: ```java private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 这里 IBinder类型的service 就是我们要绑定的那个service // 通过这个service,Activity就可以调用MyBindService.MyBinder中的方法 } @Override public void onServiceDisconnected(ComponentName name) { Log.i(TAG, "onServiceDisconnected: "); } }; ``` 然后,组件可以通过调用`bindService()`方法来绑定Service,并在不需要时调用`unbindService()`方法来解绑[^5]。 ### Service的应用场景 Service非常适合用来执行那些不需要用户界面但需要长时间运行的任务。比如播放音乐、下载文件、处理网络请求等。此外,Service还可以与其他组件进行交互,包括跨进程通信(IPC)[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值