浅谈Android四大组建之一Service---Service与Activity的绑定

从上一篇文章我们学会了如何创建Service,我们通过监听一个按钮,然后再按钮里面通过意图来启动Service。但是我们有没有发现,启动服务以后,Activity和Service之间的联系好像就断开了。两个组建么有太多的关联。那么,这一篇文章我们来介绍,服务和活动之间的绑定。BYW,服务可以和任何一个活动绑定,而且绑定后都可以获取到相同的Binder实例。

关于服务的一点小知识:

一个服务,如果我们调用了startService(),然后再去调用stopService(),那么onDestroy()就会执行,

如果我们调用了bindService()方法后,又去调用unbindService(),那么onDestroy()就也执行,

但是,如果你同时调用了startService()和bindService(),然后只是调用了stopService()或只是调用了unbindService(),那么onDestory()是不会执行的。也就是说,如果你同时调用了startService()和bindService(),那么你就必须同时调用stopService()和unbindService(),onDestory()才会执行。

 

下面我们还是一样,先看代码吧.

首先是布局文件,布局文件没什么,就是放置四个按钮而已

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical"
 6     android:paddingBottom="@dimen/activity_vertical_margin"
 7     android:paddingLeft="@dimen/activity_horizontal_margin"
 8     android:paddingRight="@dimen/activity_horizontal_margin"
 9     android:paddingTop="@dimen/activity_vertical_margin"
10     tools:context="com.example.servicedemo.MainActivity" >
11     
12     <Button 
13         android:onClick="onclick"
14         android:id="@+id/bt_start"
15         android:layout_width="match_parent"
16         android:layout_height="wrap_content"
17         android:text="开启服务"
18         />
19     
20      <Button 
21          android:onClick="onclick"
22         android:id="@+id/bt_stop"
23         android:layout_width="match_parent"
24         android:layout_height="wrap_content"
25         android:text="关闭服务"
26         />
27      
28        <Button 
29         android:onClick="onclick"
30         android:id="@+id/bt_bind"
31         android:layout_width="match_parent"
32         android:layout_height="wrap_content"
33         android:text="绑定服务"
34         />
35     
36      <Button 
37          android:onClick="onclick"
38         android:id="@+id/bt_unbind"
39         android:layout_width="match_parent"
40         android:layout_height="wrap_content"
41         android:text="解绑服务"
42         />
43 
44 
45 </LinearLayout>
activity_main.xml

 然后是Service文件

 1  package com.example.servicedemo;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.Binder;
 6 import android.os.IBinder;
 7 import android.widget.Toast;
 8 
 9 /**
10  *************************************************************** 
11  * 
12  * @版权 LinFeng
13  * 
14  * @作者 LinFeng
15  * 
16  * @版本 1.0
17  * 
18  * @创建日期 2016-6-8
19  * 
20  * @功能描述 
21  ***************************************************************** 
22  */
23 public class MyService extends Service{
24     
25 
26     private MusuicBinder mBinder = new MusuicBinder();
27     /**
28      * Service中唯一的抽象方法,必须在子类中实现,这里返回一个MusicBinder的实例是为了能和活动绑定
29      */
30     @Override
31     public IBinder onBind(Intent intent) {
32         return mBinder;
33     }
34     
35     /**
36      * 服务创建的时候调用
37      */
38     @Override
39     public void onCreate() {
40         super.onCreate();
41     }
42     
43     /**
44      * 每一次服务启动的时候调用,这个案例中,每点击一次start service都会执行的方法
45      * oncreate只是第一次点击的时候执行
46      */
47     @Override
48     public int onStartCommand(Intent intent, int flags, int startId) {
49         return super.onStartCommand(intent, flags, startId);
50     }
51     
52     /**
53      * 服务销毁的时候调用
54      */
55     @Override
56     public void onDestroy() {
57         super.onDestroy();
58     }
59     
60     /**
61      * 这里我们虚拟出一个后台播放音乐的服务
62      */
63     class MusuicBinder extends Binder{
64         
65         /**
66          * 虚拟方法,假装我在播放音乐。。。。
67          */
68         public void playMusic(){
69             Toast.makeText(MyService.this, "音乐在后台播放", Toast.LENGTH_SHORT).show();
70         }
71         
72         /**
73          * 虚拟方法,假装我能拿到播放的进度。。。
74          */
75         public void getProgress(){
76             Toast.makeText(MyService.this, "播放到80%", Toast.LENGTH_SHORT).show();
77         }
78     }
79     
80 }
MyService

然后就是主界面的文件

  1 package com.example.servicedemo;
  2 
  3 import android.app.Activity;
  4 import android.content.ComponentName;
  5 import android.content.Intent;
  6 import android.content.ServiceConnection;
  7 import android.os.Bundle;
  8 import android.os.IBinder;
  9 import android.view.View;
 10 import android.widget.Toast;
 11 
 12 public class MainActivity extends Activity {
 13 
 14     private MyService.MusuicBinder mBinder;
 15     
 16     boolean bindService ;//用于判断是否有绑定服务
 17 
 18     private ServiceConnection connection = new ServiceConnection() {
 19 
 20         /**
 21          * 解除绑定服务的时候回掉
 22          */
 23         @Override
 24         public void onServiceDisconnected(ComponentName name) {
 25 
 26         }
 27 
 28         /**
 29          * 服务被绑定的时候回掉
 30          */
 31         @Override
 32         public void onServiceConnected(ComponentName name, IBinder service) {
 33 
 34             mBinder = (MyService.MusuicBinder) service;
 35 
 36             /**
 37              * 调用服务里面的方法
 38              * 成功绑定服务的时候,就会执行这个方法
 39              */
 40             mBinder.playMusic();
 41             // mBinder.getProgress();
 42         }
 43     };
 44     @Override
 45     protected void onCreate(Bundle savedInstanceState) {
 46         super.onCreate(savedInstanceState);
 47         setContentView(R.layout.activity_main);
 48         
 49     }
 50 
 51     public void onclick(View v) {
 52         
 53         switch (v.getId()) {
 54             case R.id.bt_start :
 55 
 56                 /**
 57                  * 服务和活动一样,都是用Intent来启动的, 其实可以把服务理解为没有界面的活动
 58                  */
 59                 Intent startintent = new Intent(this, MyService.class);
 60                 startService(startintent);
 61 
 62                 break;
 63             case R.id.bt_stop :
 64 
 65                 Intent stopintent = new Intent(this, MyService.class);
 66                 stopService(stopintent);
 67 
 68                 break;
 69             case R.id.bt_bind :
 70 
 71                 Intent bindIntent = new Intent(this, MyService.class);
 72                 bindService = bindService(bindIntent, connection,
 73                         BIND_AUTO_CREATE);
 74                 if (bindService) {
 75                     Toast.makeText(this, "服务已经绑定", Toast.LENGTH_SHORT).show();
 76                 }
 77                 break;
 78             case R.id.bt_unbind :
 79 
 80                 /**
 81                  * 在调用这个unbindService接触绑定的方法的时候一定要十分注意
 82                  * 做非空判断,没有绑定服务的情况下去调用解除绑定的方法,会导致
 83                  * 程序直接崩溃
 84                  */
 85                 if (bindService) {
 86                     bindService = false;
 87                     unbindService(connection);
 88                     Toast.makeText(this, "绑定已经解除", Toast.LENGTH_SHORT).show();
 89                 } else {
 90                     Toast.makeText(this, "服务没有绑定绑定", Toast.LENGTH_SHORT).show();
 91                 }
 92 
 93                 break;
 94 
 95             default :
 96                 break;
 97         }
 98     }
 99 
100 }
MainActivity

然后就是运行截图了。由于这个例子很简单,讲解就看注释可以了

posted @ 2016-06-09 22:51  _Vincent  阅读(1496)  评论(0编辑  收藏  举报