zoukankan      html  css  js  c++  java
  • Android之Service

    Android之Service的生命周期和启动方式的特点比较:

      Service是Android系统中的四大组件之一,它和Activity的级别差不多,但是只能在后台运行,并且可以和其他的组件进行交互。Service可以在很多场合的应用中使用,例如播放音乐的时候用户启动了其它的Activity这个时候程序要在后台继续播放,比如在后台记录地理位置信息的改变等等,总之服务是在后台运行的。

    1. 服务是在后台运行的,可以理解为没有界面的Activity。
    2. 定义四大组件的方式都一样,在配置文件中进行注册。
    • <!-- 进行注册服务 -->
      <service android:name=".MyService"></service>

          3.  定义一个类继承Service类

    一、start启动服务的特点:

    1. 服务通过startService方式开启,第一次点击按钮开启服务,会执行onCreate()和onStart()/onStartCommand()方法
    2. 如果第二次再开启点击按钮开启服务,服务之后会执行onStartCommand()方法
    3. 服务被开启后,会在设置页面里的应用程序中的正在运行里面找到这个服务
    4. startService方式开启服务,服务就会在后台长期运行,直到用户手工停止或是调用stopService方法服务才会被销毁
    public class MyService extends Service {
        public static final String tag = "start方式开启服务---";
    
        @Override
        public boolean onUnbind(Intent intent) {
            Log.e(tag, "onUnbind");
            return super.onUnbind(intent);
        }
        @Override
        //第一次创建时调用
        public void onCreate() {
            Log.e(tag, "onCreate");
            super.onCreate();
        }
    
        //启动服务时调用
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.e(tag, "onStartCommand");
            return super.onStartCommand(intent, flags, startId);
        }
        
        //销毁服务时调用
        @Override
        public void onDestroy() {
            Log.e(tag, "onDestroy");
            super.onDestroy();
        }
    }
    //第一次点击按钮开启服务的时候
    10-23 15:09:57.487  29774-29774/com.example.lenovo.servicedemo E/start方式启动服务---﹕ onCreate
    10-23 15:09:57.487  29774-29774/com.example.lenovo.servicedemo E/start方式启动服务---﹕ onStartCommand
    
    //之后再点击开启按钮开启服务,只执行onStartCommand()
    10-23 15:10:04.547  29774-29774/com.example.lenovo.servicedemo E/start方式启动服务---﹕ onStartCommand
    
    //点击按钮stopService之后服务销毁 或者是在设置-> 应用程序 -> 正在运行 中手动把该服务停止的之后执行onDestory销毁服务
    10-23 15:10:06.921  29774-29774/com.example.lenovo.servicedemo E/start方式启动服务---﹕ onDestroy

      

    二、Bind绑定服务:

      BindService是应用组件(客户端)通过调用bindService()方法能够绑定服务,然后Android系统会调用服务的onBind()回调方法,这个方法会返回一个跟服务端交互的IBinder对象。这个绑定是异步的,bindService()方法立即返回,并且不给客户端返回IBinder对象。要接收IBinder对象,客户端必须创建一个ServiceConnection类的实例,并且把这个实例传递给bindService()方法。ServiceConnection对象包含了一个系统调用的传递IBinder对象的回调方法。注意:只有Activity,Service和内容提供者(Content Provider)能够绑定服务,广播接收器不能绑定服务。

    bind服务的特点:

    1. 当点击按钮第一次开启服务,会执行服务的onCreate()方法和onBind()方法
    2. 当第二次点击按钮再调用bindService,服务没有响应
    3. 当Activity销毁的时候服务也销毁,不求同时生,但求同时死
    4. 通过bind方式开启服务,服务不能再设置界面里找到
    5. bindService不能多次解绑,多次解绑会报错
    public class MyService extends Service {
        public static final String tag = "bind方式开启服务---";
       
        @Override
        //创建服务时调用
        public void onCreate() {
            Log.e(tag, "onCreate");
            super.onCreate();
        }
    
        //绑定服务的时候调用
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            Log.e(tag, "onUnbind");
            return super.onUnbind(intent);
        }
    
        //销毁服务时调用
        @Override
        public void onDestroy() {
            Log.e(tag, "onDestroy");
            super.onDestroy();
        }
        
    }
    //第一次点击bind服务的按钮
    10-23 15:35:02.301 18879-18879/com.example.lenovo.servicedemo E/bind方式开启服务---﹕ onCreate 10-23 15:35:02.301 18879-18879/com.example.lenovo.servicedemo E/bind方式开启服务---﹕ onBind
    //第二次点击bind按钮没有响应

    //点击unbind解绑服务,服务销毁 10-23 15:35:05.251 18879-18879/com.example.lenovo.servicedemo E/bind方式开启服务---﹕ onUnbind 10-23 15:35:05.251 18879-18879/com.example.lenovo.servicedemo E/bind方式开启服务---﹕ onDestroy
    //再次点击解绑,即多次解绑服务报错 10-23 15:35:17.121 18879-18879/com.example.lenovo.servicedemo E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.IllegalArgumentException: Service not registered: com.example.lenovo.servicedemo.MainActivity$MyConn@429ee820

    为什么要引入bindService:目的是为了调用服务里面的方法

    • 通过bindService方式调用服务方法的过程
      • 定义一个服务,服务里面有一个方法需要Activity调用
      1. //服务里面定义一个方法方法,之后需要在Activity里面调用
        public void serviceMethod(){
            Toast.makeText(getApplicationContext(), "这是服务里面的方法", Toast.LENGTH_SHORT).show();
        }
      • 定义一个类对象MyBinder继承Binder
      1. //定义一个类继承 IBinder接口的实现子类Binder类
        class MyBinder extends Binder {
           public void callServiceMethod(){
              serviceMethod();
           }
        }
      • 在onBind()方法里面把我们定义的MyBinder类对象返回
      1. //绑定服务的时候调用
        @Override
        public IBinder onBind(Intent intent) {
            return new MyBinder(); //返回一个MyBinder对象
        }
      • 在Activity的onCreate()方法里面调用bindService,目的是为了来获取我们的定义的MyBinder对象
      1. class MyConn implements ServiceConnection{
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                binder = (MyService.MyBinder)service; //获取MyBinder对象
            }
        
            @Override
            public void onServiceDisconnected(ComponentName name) {
        
            }
        }
      • 拿到MyBinder对象后就可以间接的调用服务里面的方法
      • public void onClickCallMethod(){
             binder.callServiceMethod();
        }
    • 通过接口调用服务中的方法: 接口可以隐藏代码内部的细节,让程序员暴露只想暴露的方法
    1. 定义一个接口Iservice,把想暴露的方法暴露在接口里面
    2. 我们定义的MyBinder对象实现我们定义的Iservice接口
    3. 在获取我们定义的MyBinder对象的方式改变了(接口类型) 
    4. interface  IService {
          public void callServiceMethod2();
      }
      //服务里面定义一个方法方法,之后需要在Activity里面调用
          public void serviceMethod(){
              Toast.makeText(getApplicationContext(), "这是服务里面的方法", Toast.LENGTH_SHORT).show();
          }
      
          public void serviceMethod2(){
              Toast.makeText(getApplicationContext(), "这是服务里面想暴露的方法", Toast.LENGTH_SHORT).show();
          }
      
          //定义一个类继承 IBinder接口的实现子类Binder类
          class MyBinder extends Binder implements IService{
              public void callServiceMethod(){
                  serviceMethod();
              }
      
              @Override
              public void callServiceMethod2() {
                  serviceMethod2();
              }
          }
    5. binder = (IService) service;

      

    音乐播放器(需要混合方式开启服务):

    需求:既想让服务在后台长期运行,又想调用服务里面的方法

    bindService:不能长期运行,但是可以调用方法

    startService:可以长期运行, 但是不可以调用方法

  • 相关阅读:
    Java 实现 蓝桥杯 生兔子问题
    Java实现 蓝桥杯 基因牛的繁殖
    Java实现 蓝桥杯 基因牛的繁殖
    Java实现 蓝桥杯 基因牛的繁殖
    Java实现 LeetCode 33 搜索旋转排序数组
    Java实现 LeetCode 33 搜索旋转排序数组
    Java实现 LeetCode 33 搜索旋转排序数组
    深入探究VC —— 资源编译器rc.exe(3)
    深入探究VC —— 编译器cl.exe(2)
    深入探究VC —— 编译器cl.exe(1)
  • 原文地址:https://www.cnblogs.com/denluoyia/p/5987021.html
Copyright © 2011-2022 走看看