我们在Service(Ⅰ)中了解了Service最基本的知识点,今天我们继续学习Service这个组件(神器)。

  先来说一下Service的生命周期:跟Activity相比,Service的生命周期就太简单了:onCreate()->onStart()->onDestroy()

  ----------------------------------------------------------------------------------------------------------------------------------------

  【主题】:Activity与Service之间的Communication

  【问题】:由上贴我们知道,当我们点击START SERVICE按钮后,服务的onCreate()和onStartCommand()方法会得到执行,此后Service是一直存在于后台运行的,Activity无法控制Service中具体的逻辑运行,那么这样Activity只相当于起到一个通知的作用,除了告诉Service你可以开始工作了。那么这样显然会分离两者之间的关联性,这也不是我们需要的结果!

  【后果】:如果出现以上的问题,那么在我们平时的项目开发过程中(拿小编做手机开发项目而言),一直存在的Service很有可能会引起功耗的问题,这将严重影响手机的运行效率!

  【要求】:我们能否将Activity与Service建立一种联系,当Activity终结之时,Service也销毁,也就是有没有办法让Activity和Service能够“不求同生,但求共死”?

  答案是肯定的!这就涉及到Service的另一个重要知识点:绑定与解绑!

  直接代码走起,看过来:

  (1)MyService.java

Java代码
  1. public class MyService extends Service{  
  2.   private static final String TAG = "MyService";  
  3.   
  4.   private DownloadBinder mBinder = new DownloadBinder();       // 定义一个DownloadBinder类  
  5.   
  6.   class DownloadBinder extends Binder {                            // 让DownloadBinder成为Binder的子类  
  7.     public void startDownload() {                      // 定义开始下载的方法  
  8.       Log.d(TAG, "startDownload executed");  
  9.     }  
  10.     public int getProgress() {                                      // 定义一个查看下载进度的方法  
  11.       Log.d(TAG, "getProgress executed");  
  12.       return 0;                                                   
  13.     }  
  14.   }  
  15.   @Nullable  
  16.   @Override  
  17.   public IBinder onBind(Intent intent) {                               // onBind()方法,这个方法将在绑定后调用  
  18.     return mBinder;                                                  // 返回IBinder的实例 --> DownloadBinder类的实例  
  19.   }  
  20.   ...                         // 这边就是之前定义好的onStart()、onStartCommand()、onDestroy()三个方法  
  21. }  

  (2)接下来,我们在Layout中添加两个按钮 BIND SERVICE 和 UNBIND SERVICE:

Android实用技术(4)—— Service简析(Ⅱ)

  (3)MainActivity.java

Java代码
  1. public class MainActivity extends Activity implements View.OnClickListener{  
  2.   
  3.   private ServiceConnection connection = new ServiceConnection() {                       // 创建一个ServiceConnection的匿名内部类  
  4.     @Override  
  5.     public void onServiceConnected(ComponentName name, IBinder service) {               // 重写onServiceConnected()方法  
  6.       MyService.DownloadBinder downloadBinder = (MyService.DownloadBinder) service;   // 向下转型取得downloadBinder实例  
  7.       downloadBinder.startDownload();                                                 // 在Activity中调用Service的方法  
  8.       downloadBinder.getProgress();                                                   // 在Activity中调用Service的方法  
  9.     }  
  10.   
  11.     @Override  
  12.     public void onServiceDisconnected(ComponentName name) {                             // 重写onServiceDisconnected()方法  
  13.     }  
  14.   };  
  15.   
  16.   @Override  
  17.   protected void onCreate(Bundle savedInstanceState) {  
  18.     super.onCreate(savedInstanceState);  
  19.     setContentView(R.layout.activity_main);  
  20.     Button startService = (Button) super.findViewById(R.id.start_service);  
  21.     Button stopService = (Button) super.findViewById(R.id.stop_service);  
  22.     Button bindService = (Button) super.findViewById(R.id.bind_service);  
  23.     Button unbindService = (Button) super.findViewById(R.id.unbind_service);          // 不解释!!!  
  24.     startService.setOnClickListener(this);  
  25.     stopService.setOnClickListener(this);  
  26.     bindService.setOnClickListener(this);  
  27.     unbindService.setOnClickListener(this);  
  28.   }  
  29.   
  30.   @Override  
  31.   public void onClick(View v) {  
  32.     switch (v.getId()) {  
  33.       case R.id.start_service:  
  34.         Intent startIntent = new Intent(this, MyService.class);            // START 服务 --> onCreate() --> onStartCommand()  
  35.         startService(startIntent);  
  36.         break;  
  37.       case R.id.stop_service:  
  38.         Intent stopIntent = new Intent(this, MyService.class);                     // STOP 服务 --> onDestroy()  
  39.         stopService(stopIntent);  
  40.         break;  
  41.       case R.id.bind_service:                                                       // 绑定 --> ?  
  42.         Intent bindIntent = new Intent(this, MyService.class);  
  43.         bindService(bindIntent, connection, BIND_AUTO_CREATE);  
  44.         break;  
  45.       case R.id.unbind_service:                                                     // 解绑 --> ?  
  46.         unbindService(connection);  
  47.         break;  
  48.       default:  
  49.         break;  
  50.     }  
  51.   }  
  52. }  

  (4)我们一起来看一下bindService(bindIntent, connection, BIND_AUTO_CREATE)这个方法:

  bindService接收了3个参数:

  bindIntent:这个参数传入的就是我们的intent,目的就是调用MyService这个服务。

  connection:这个参数传入的就是创建好的ServiceConnection的实例,这个参数代表着我们的Activity是要和Service绑定在一起的!

  BIND_AUTO_CREATE:这是一个FLAG,表示在活动和服务进行绑定后自动创建服务。注意!注意!是自动创建服务,也就是说MyService会执行onCreate()方法,但是不会执行onStartCommand()方法!

  (5)好了,说到这边,我们直接来看看代码最终的效果吧:

Android实用技术(4)—— Service简析(Ⅱ)

Android实用技术(4)—— Service简析(Ⅱ)

  小编通过排列组合,对按钮进行了狂烈的点击,跟大家一起分享一下上图中Log的情况,分3种情况:

  (1)START SERVICE + STOP SERVICE:

  当我们先点击START SERVICE:此时服务启动,调用onCreat()和onStartCommand()方法;

  当我们后点击STOP SERVICE:此时,服务被销毁,调用onDestroy()方法。

  (2)BIND SERVICE + UNBIND SERVICE:

  当我们先点击BIND SERVICE:此时服务仅仅是创建,并未启动!所以调用的只是onCreate()方法。此时Activity与Service绑定,会同时调用onBind()方法,此时onServiceConnected()方法会被执行,还记的onBind()方法的返回类型不?我们通过Log可以很明显发现,Activity调用了服务内部的两个自定义方法。

  当我们后点击UNBIND SERVICE:由于服务还未启动,而BIND SERVICE只是将服务创建好并与活动进行绑定,那么解绑后,势必会销毁这个Service,所以onDestroy()被执行!

  (3)START SERVICE + BIND SERVICE + UNBIND SERVICE + STOP SERVICE:

  这么长的一串字符,小编看的都想吐~~~~

  分析吧:

  1、我们先点击START SERVICE:onCreat()和onStartCommand()方法被执行,这个就不用多说了;

  2、然后点击UNBIND SERVICE:这个时候其实活动已经在后台运行了,我们此时将活动和服务绑定,那么onCreate()不会再执行,只会执行onServiceConnected()方法,Log里面打出来看的很清楚。

  3、此时你如果手贱,想STOP SERVICE:那么恭喜你,毫无反应!为什么?因为你都没解绑,你怎么销毁?

  4、OK,那我们先解绑,我们点击UNBIND SERVICE:此时一个奇怪的现象发生了,LOG日志没有打印出Destroy()这个方法啊?没有被执行啊!不是说bind了Service之后,unbind就会销毁这个服务吗?这跟我们第(2)条不符合啊。

  5、好吧,我们来看看,其实原因很简单:我们先start了Service,那么此时服务已经在后台运行了,这个时候你bind,让Service和Activity绑定,其实是没有什么意义的。但是既然绑定了,你如果不解绑,那么Destroy()毫无用武,所以,这种情况和(2)中分析的还是有区别的,此是解绑完后,服务还是舒舒服服的在后台运行,所以,要想干掉这个服务,你必须要STOP SERVICE。

  我想你是不是要好好消化一下,很快就可以理解的!

  6、放我们解绑后,再STOP SERVICE:这个时候Service就被枪毙了!

本文发布:Android开发网
本文地址:http://www.jizhuomi.com/android/course/698.html
2017年7月26日
发布:鸡啄米 分类:Android开发教程 浏览: 评论:0