Service是运行在后台的,没有界面的,用来处理耗时比较长的。Service不是一个单独的进程,不是一个单独的线程。
Service有两种类型:
本地服务(Local Service):用于应用程序内部
远程服务(Remote Sercie):用于android系统内部的应用程序之间
本地服务用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较 好。
远程服务可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。
Service的生命周期:
Service的启动方法:
服务不能自己运行,需要通过调用Context.startService() 或 Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。
使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。
使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同生,但求同死”的特点。
Service的启动方法:
1.通过startService() onCreate --> onStartCommand()--> onDestroy()
startService(): onCreate --> onStartCommand()
stopService:onDestroy()
采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法.
接着调用onStartCommand()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStartCommand()方法。
采用startService()方法启动的服务,只能调用Context.stopService()方法结 束服务,服务结束时会调用onDestroy()方法。
2.通过bindService() onCreate()-->onBind()--> onUnbind()-->onDestroyed()
bindService():调用者和Service绑定在一起
unbindService(): onUnbind()-->onDestroyed()
采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,
接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。
如调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。
如调用者希望与正在绑定的服务解除绑定,可调用unbindService()方法,调用该方法会导致系统调用的 onUnbind()-->onDestroy()方法
先演示一个startService的例子,这个demo主要是播放器。功能是首先有个三秒钟的开场白,然后跳转到PlayerActivity。PlayerActivity这个类可以调用MusicService的属性。
首先给大家看开场白的布局文件main.xml
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:orientation="vertical"
4 android:layout_width="fill_parent"
5 android:layout_height="fill_parent"
6 android:background="@drawable/background"
7 >
8 <ImageView
9 android:id="@+id/image1"
10 android:layout_width="fill_parent"
11 android:layout_height="fill_parent"
12 android:src="@drawable/a1"/>
13 </LinearLayout>
这个布局主要是给开场白用的,也就是MusicPlayerActivity.java这个类
1 package cn.shaoyangjiang.com;
2
3 import android.app.Activity;
4 import android.content.Intent;
5 import android.os.Bundle;
6 import android.view.Window;
7 import android.os.Handler;
8 import android.view.WindowManager;
9
10 public class MusicPlayerActivity extends Activity {
11 @Override
12 public void onCreate(Bundle savedInstanceState) {
13 super.onCreate(savedInstanceState);
14 //全屏
15 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
16 requestWindowFeature(Window.FEATURE_NO_TITLE);
17 setContentView(R.layout.main);
18 //开场白,延时3秒进入PlayerActivity
19 new Handler().postDelayed(new Runnable(){
20 @Override
21 public void run() {
22 Intent intent = new Intent(MusicPlayerActivity.this,PlayerActivity.class);
23 startActivity(intent);
24 finish();
25 }
26
27 }, 3000);
28
29 }
30 }
然后看主程序的布局文件player.xml
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 android:orientation="vertical"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent"
7 android:background="@drawable/background">
8 <ImageView
9 android:src="@drawable/a2"
10 android:layout_width="fill_parent"
11 android:layout_height="380dp"/>
12 <LinearLayout
13 android:layout_width="fill_parent"
14 android:layout_height="wrap_content"
15 android:orientation="horizontal">
16 <ImageButton
17 android:layout_width="wrap_content"
18 android:layout_height="wrap_content"
19 android:id="@+id/stop"
20 android:background="@drawable/stop_button_on"/>
21 <ImageButton
22 android:layout_width="wrap_content"
23 android:layout_height="wrap_content"
24 android:id="@+id/play"
25 android:background="@drawable/play"/>
26 </LinearLayout>
27
28 </LinearLayout>
主程序代码:
1 package cn.shaoyangjiang.com;
2
3 import android.app.Activity;
4 import android.content.Intent;
5 import android.os.Bundle;
6 import android.view.View;
7 import android.widget.ImageButton;
8
9 public class PlayerActivity extends Activity{
10 public static final int PLAY = 1;
11 public static final int PAUSE = 2;
12 private ImageButton startButton;
13 private ImageButton stopButton;
14 boolean isPlaying = false;
15
16 @Override
17 protected void onCreate(Bundle savedInstanceState) {
18 super.onCreate(savedInstanceState);
19 setContentView(R.layout.player);
20 //得到控件
21 startButton =(ImageButton)findViewById(R.id.play);
22 stopButton =(ImageButton)findViewById(R.id.stop);
23 //跳转到MusicService.java文件
24 final Intent intent = new Intent(PlayerActivity.this,MusicService.class);
25 //对startButton进行监听
26 startButton.setOnClickListener(new View.OnClickListener() {
27 @Override
28 public void onClick(View arg0) {
29 if(!isPlaying){
30 try{
31 //在intent里传入键值对,启动服务
32 intent.putExtra("flag", 1);
33 startService(intent);
34 } catch (Exception e){
35 e.printStackTrace();
36 }
37 //把开始按钮设为停止按钮
38 startButton.setBackgroundResource(R.drawable.pause);
39 isPlaying = true;
40 } else{
41 try{
42 intent.putExtra("flag", 2);
43 startService(intent);
44 } catch(Exception e){
45 e.printStackTrace();
46 }
47 startButton.setBackgroundResource(R.drawable.play);
48 isPlaying = false;
49
50 }
51 }
52 });
53 //对停止按钮监听,按下时关闭服务
54 stopButton.setOnClickListener(new View.OnClickListener() {
55 @Override
56 public void onClick(View arg0) {
57 stopService(intent);
58 finish();
59 }
60 });
61 }
62
63 }
再是服务
1 package cn.shaoyangjiang.com;
2
3 import android.app.Service;
4 import android.content.Intent;
5 import android.media.MediaPlayer;
6 import android.os.IBinder;
7
8 public class MusicService extends Service{
9 public static final int PLAY = 1;
10 public static final int PAUSE = 2;
11 public static MediaPlayer mediaPlayer;
12 @Override
13 public IBinder onBind(Intent arg0) {
14 return null;
15 }
16 @Override
17 public void onCreate() {
18 //初始化音乐
19 mediaPlayer =MediaPlayer.create(getApplicationContext(), R.raw.away);
20 }
21 @Override
22 public void onDestroy() {
23 mediaPlayer.stop();
24 super.onDestroy();
25 }
26 @Override
27 public int onStartCommand(Intent intent, int flags, int startId) {
28 int flag = intent.getIntExtra("flag",0);
29 //判断标识符
30 if(flag == PLAY){
31 mediaPlayer.start();
32 }else {
33 if(flag == PAUSE){
34 mediaPlayer.pause();
35 }
36 }
37
38 return super.onStartCommand(intent, flags, startId);
39
40 }
41
42 }
最后是注册文件
1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="cn.shaoyangjiang.com"
4 android:versionCode="1"
5 android:versionName="1.0">
6 <uses-sdk android:minSdkVersion="8" />
7
8 <application android:icon="@drawable/icon" android:label="@string/app_name">
9 <activity android:name=".MusicPlayerActivity"
10 android:label="@string/app_name">
11 <intent-filter>
12 <action android:name="android.intent.action.MAIN" />
13 <category android:name="android.intent.category.LAUNCHER" />
14 </intent-filter>
15 </activity>
16 <activity android:name=".PlayerActivity"
17 android:label="@string/app_name">
18 </activity>
19 <service android:enabled="true" android:name=".MusicService">
20 </service>
21 </application>
22 </manifest>
效果图: