从上一篇文章我们学会了如何创建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>
然后是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 }
然后就是主界面的文件
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 }
然后就是运行截图了。由于这个例子很简单,讲解就看注释可以了