zoukankan      html  css  js  c++  java
  • Android学习笔记(八)深入分析Service启动、绑定过程

      Service是Android中一个重要的组件,它没有用户界面,可以运行在后太做一些耗时操作。Service可以被其他组件启动,甚至当用户切换到其他应用时,它仍然可以在后台保存运行。Service 是Android四大组件中与Activity最相似的组件,都代表可执行的程序,区别在于:Service一直运行在后台,没有界面,一旦Service被启动,即完全具有自己的生命周期。

    一、创建一个Service

      在创建Service时,步骤与Activity很像:

      1.继承Service,创建Service子类。

      2.在AndroidManifest.xml文件中配置该Service。

    下面创建一个最基本的Service组件:

    MyService.java

     1 public class MyService extends Service {
     2     
     3     //必须实现的方法,用户返回Binder对象
     4     @Override
     5     public IBinder onBind(Intent intent) {
     6         System.out.println("--onBind()--");
     7         return null;
     8     }
     9     
    10     //创建Service时调用该方法,只调用一次
    11     @Override
    12     public void onCreate() {
    13         super.onCreate();
    14         System.out.println("--onCreate()--");
    15     }
    16     
    17     //每次启动Servcie时都会调用该方法
    18     @Override
    19     public int onStartCommand(Intent intent, int flags, int startId) {
    20         System.out.println("--onStartCommand()--");
    21         return super.onStartCommand(intent, flags, startId);
    22     }
    23     
    24     //解绑Servcie调用该方法
    25     @Override
    26     public boolean onUnbind(Intent intent) {
    27         System.out.println("--onUnbind()--");
    28         return super.onUnbind(intent);
    29     }
    30     
    31     //退出或者销毁时调用该方法
    32     @Override
    33     public void onDestroy() {
    34         System.out.println("--onDestroy()--");
    35         super.onDestroy();
    36     }
    37     
    38 }

    然后再Manifest.xml文件中红配置一下

    1 <service 
    2      android:name=".MyService">
    3 </service>

     为了待会测试的方便,我们在该Service的onCreate()方法里面写一个方法,开启一个线程,让其不断输出“Service运行中”的状态。补充后的MyService类如下:

     1 public class MyService extends Service {
     2     
     3     private boolean serviceRunning = false;
     4     // 必须实现的方法,用户返回Binder对象
     5     @Override
     6     public IBinder onBind(Intent intent) {
     7         System.out.println("--onBind()--");
     8         return null;
     9     }
    10 
    11     // 创建Service时调用该方法,只调用一次
    12     @Override
    13     public void onCreate() {
    14         super.onCreate();
    15         System.out.println("--onCreate()--");
    16         serviceRunning = true;
    17         new Thread() {
    18             @Override
    19             public void run() {
    20                 while (serviceRunning) {
    21                     System.out.println("---Service运行中---");
    22                     try {
    23                         sleep(1000);
    24                     } catch (InterruptedException e) {
    25                         e.printStackTrace();
    26                     }
    27                 }
    28             };
    29         }.start();
    30     }
    31 
    32     // 每次启动Servcie时都会调用该方法
    33     @Override
    34     public int onStartCommand(Intent intent, int flags, int startId) {
    35         System.out.println("--onStartCommand()--");
    36         return super.onStartCommand(intent, flags, startId);
    37     }
    38 
    39     // 解绑Servcie调用该方法
    40     @Override
    41     public boolean onUnbind(Intent intent) {
    42         System.out.println("--onUnbind()--");
    43         return super.onUnbind(intent);
    44     }
    45 
    46     // 退出或者销毁时调用该方法
    47     @Override
    48     public void onDestroy() {
    49         serviceRunning = false;
    50         System.out.println("--onDestroy()--");
    51         super.onDestroy();
    52     }
    53 
    54 }

    代码分析:首先我们定义一个boolean类型的变量serviceRunning,用来控制新线程中是否输出“---Service运行中---”,通过这样的方式更能让我们直观地看到Servcie的运行状态。

    二、启动Service

      启动Service和启动一个Activity类似,也是先定义一个Intent让它指向需要启动Service,然后通过调用startService()方法,启动即可,具体代码如下:

    1 btn_start_service.setOnClickListener(new OnClickListener() {
    2      @Override
    3      public void onClick(View arg0) {
    4          intent = new Intent(this, MyService.class);
    5 startService(intent); 6 } 7 });

     代码分析:在主界面中添加了一个按钮,在按钮中首先定义了一个Intent,然后通过startService启动该Intent从而就可以启动Service,与启动一个Activity的方法简直一样啊。

    三、停止Service

      与启动Service相对应的就是停止Service,通过stopService()即可完成此操作,如下:

    1 btn_stop_service.setOnClickListener(new OnClickListener() {
    2      @Override
    3      public void onClick(View arg0) {
    4          stopService(intent);
    5          }
    6 });

     当然,这里Intent需要与startService使用的为一个。

    四、绑定Service

      绑定Service用是通过调用bindService(Intent service, ServiceConnection conn, int flags)方法来实现的,单看参数就知道与启动Service比起来,会麻烦一些,大体分为如下三步:

      第一步:重写onBind()方法,返回Service实例

      Service可以让Activity绑定,以获得更加详细的接口。如果先想让一个Service支持绑定,需要实现Service中得onBind()方法,并返回被绑定Service的当前实例,如下:

    1     public IBinder onBind(Intent intent) {
    2         System.out.println("--onBind()--");
    3         return new MyBinder();
    4     }
    5     
    6     public class MyBinder extends Binder{
    7         MyService getService(){
    8             return MyService.this;
    9     }

      第二步:实现一个ServiceConnection  

      另外,Service和其他组件的链接表示为一个ServiceConnection,要想一个Service和其他组件绑定,需要实现一个新的ServiceConnection,建立一个链接后,就可以通过重写onServiceConnected()方法和onServiceDisconnected()方法,来获得对Service实例的引用。代码如下:

     1 MyService.MyBinder binder = null;
     2 class MyServiceConn implements ServiceConnection {
     3         // 服务被绑定成功之后执行
     4         @Override
     5         public void onServiceConnected(ComponentName name, IBinder service) {
     6             //service为onBind方法返回的Service实例
     7             binder = (MyService.MyBinder) service;
     8         }
     9         
    10         // 服务奔溃或者被杀掉执行
    11         @Override
    12         public void onServiceDisconnected(ComponentName name) {
    13        binder = null;
    14         }
    15 }

      第三步:调用bindService执行绑定Service

      要想绑定需要给bindService()除了需要给他传递一个需要的Intent和一个ServiceConnection实例外,还需要指定一个标示,如下:

    1 btn_bind_service.setOnClickListener(new OnClickListener() {
    2             @Override
    3             public void onClick(View arg0) {
    4                 bindService(intent, myServiceConn, Context.BIND_AUTO_CREATE);
    5             }
    6 });

      其中,myServiceConn为第二步中MyServiceConn实例,Context.BIND_AUTO_CREATE即为标示。

    五、解绑Service

      解绑Service是通过unbindService实现的,如下:

    1 btn_unbind_service.setOnClickListener(new OnClickListener() {
    2             @Override
    3             public void onClick(View arg0) {
    4                 if (binder != null) {
    5                     unbindService(myServiceConn);
    6                 }
    7             }
    8 });

      这里需要注意的是,unbindService方法中传入的ServiceConnection实例一定要跟绑定时的一致,否则可能会导致程序崩溃。

    六、试验

      主界面简单,只有四个按钮,如下:

        

      1、当按下startService按钮,然后再按下stopService按钮时,日志如下:

      

      2、当按下bindService,然后再按下unbindService时,日志如下:

      

      3、当按下startService接着按bindService时,这时候就需要unbindService和stopService都按下后才能停止Service,日志如下:

      

    七、总结

      启动Service和停止Service是一一对应的,绑定Service和解绑Servcie是一一对应的,如果同时启动和绑定了Service,必须通过解绑和停止Service才能使该Service真正停止。

    声明:欢迎转载,转载时请注明本文链接。

  • 相关阅读:
    安装并运行Nacos
    为什么浏览器记住密码会影响表单?
    Oracle数据库的函数
    前端axios传递一个包含数组的对象到后台,后台可以用String接收,也可以用List集合接收
    文字链接Link
    DatePicker日期选择器的使用
    前端解决查询慢的问题
    【华为云技术分享】自动驾驶网络系列四:我们谈自动驾驶网络到底在谈什么?
    【华为云技术分享】低代码开发平台发展趋势:低代码——炒作还是趋势?
    【华为云技术分享】【昇腾】ModelArts与Atlas 200 DK云端协同开发——行人检测Demo(提供完整Demo)
  • 原文地址:https://www.cnblogs.com/codingblock/p/4842224.html
Copyright © 2011-2022 走看看