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:可以长期运行, 但是不可以调用方法

  • 相关阅读:
    处理MySQL的ibdata1文件过大问题
    关于mysql启动问题---mysqld_safe mysqld from pid file * ended
    mysql数据库指定ip远程访问
    关于access_log 日志文件以及ip、uv和pv的定义
    nginx配置及内核优化详解
    LN : leetcode 746 Min Cost Climbing Stairs
    LN : leetcode 684 Redundant Connection
    LN : leetcode 730 Count Different Palindromic Subsequences
    LN : leetcode 516 Longest Palindromic Subsequence
    LN : leetcode 215 Kth Largest Element in an Array
  • 原文地址:https://www.cnblogs.com/denluoyia/p/5987021.html
Copyright © 2011-2022 走看看