zoukankan      html  css  js  c++  java
  • Android Service 之三(Bind Service, 继承自 Binder 类)

    启动Service有两种方式:startService 与 bindService。前者已经说过如何使用,所以,这篇贴子主要是关于 bind service的。 这里所讨论的是仅针对那些被绑定的service的,而那些既被startService() 又被 bindService() 的 service 不在此范围内。

    ① Bind Service就像是C/S架构中的服务端,其他组件(比如 Activity)绑定到它(通过 bindService()),可以向它发送请求,可以接受从它返回的响应,它甚至还提供了进程间通信(IPC)功能。

    ② 一个service要想能够被其他组件绑定,那么它的 onBind() 方法必须被实现,且必须返回一个 IBinder 对象,然后其他组件可以通过这个 IBinder 对象与该 service 进行通讯。

    ③ 多个client可以绑定至同一个service,但该 service 的onBind() 方法只会在第一个 client 绑定至其的时候被调用,当其他 client 再次绑定到它的时候,并不会调用  onBind() 方法,而是直接返回第一次被调用时产生的那个 IBinder 对象。也就是说,在其生命周期内,onBind() 只会被调用一次。

    ④ Bind Service 的生命周期如下图所示:



     

    ⑤ Bind Service 不会在后台无限期的一直运行,而是当所有绑定至其的组件都调用了 unbindService() 进行解绑之后,系统就会将其停掉以回收资源。

    ⑥ 当我们要实现一个 Bind Service 的时候,最重要的就是实现它的 onBind() 方法以返回一个 IBinder 对象

    要生成一个 Bound Service ,共有三种方式:继承自 Binder 类,使用 Messenger ,使用 AIDL。下面且听小生一一道来。

    第一种:继承自 Binder 类

    需要注意的是,这种方式仅仅适用于这种场合:service 与 application 在同一个进程中。这种场合也是最最常见的。

    它分以下几个步骤:

    a. 在你的 service 类中声明一个内部类来继承 Binder 类。在该内部类中,最好提供一个公共方法来返回你的 service 实例。

    b. 在你的 service 类中需要声明一个这个内部类的实例,以供在 onBind() 方法中返回

    c. 在 client 端,在 onServiceConnected() 方法中得到从 onBind() 方法中返回的 IBinder 对象,然后可以通过该 对象中的公共方法得到相应的 service 实例,正如 第一个步骤 所说的那样。

    d. 在 service 中提供公共方法, 这样就可以在组件(如 Activity 中调用这些公共方法了)

    下面给出一例:

    service 代码

    public class BindServiceWithIBinder extends Service {
    
        private static final String TAG = "BindServiceWithIBinder";
    
        private final MyIBinder myIBinder = new MyIBinder();
    
        /**
         * bindService() 时,调用的是这个方法,而非 onStartCommnad() 方法
         */
        @Override
        public IBinder onBind(Intent intent) {
            // 在主 Activity 上的 TextView 中打印出一行LOG
            MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                    MyServiceActivity.UPDATE_VIEW, TAG + " ----> onBind"));
            return myIBinder;
        }
    
        @Override
        public void onCreate() {
            MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                    MyServiceActivity.UPDATE_VIEW, TAG + " ----> onCreate"));
        }
    
        @Override
        public void onDestroy() {
            MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                    MyServiceActivity.UPDATE_VIEW, TAG + " ----> onDestroy"));
        }
    
        @Override
        public void onRebind(Intent intent) {
            MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                    MyServiceActivity.UPDATE_VIEW, TAG + " ----> onRebind"));
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                    MyServiceActivity.UPDATE_VIEW, TAG + " ----> onStartCommand"));
            return START_STICKY;
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                    MyServiceActivity.UPDATE_VIEW, TAG + " ----> onUnbind"));
            return super.onUnbind(intent);
        }
    
        /**
         * 声明一个 Binder 类的实现类,供在 onBind() 方法中返回该类的一个实例
         * @author 001718
         *
         */
        public class MyIBinder extends Binder {
            public Service getService() {
                MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                        MyServiceActivity.UPDATE_VIEW,
                        "BindServiceWithIBinder.MyIBinder.getService()"));
                return BindServiceWithIBinder.this;
            }
        }
    
        /**
         * service 提供的公共方法,在activity中可以调用
         */
        public void download() {
            try {
                MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                        MyServiceActivity.UPDATE_VIEW, TAG
                                + " ----> download(): 文件下载中..."));
                Thread.sleep(3000);
                MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                        MyServiceActivity.UPDATE_VIEW, TAG
                                + " ----> download(): 文件下载完成..."));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

     主 Activity 中的相应关键代码为:

    private void doUnbindService() {
            if (isBound) {
                unbindService(myLocalServiceConnection);
                isBound = false;
            }
        }
    
        private void doBindService() {
            Log.i("bind", "begin to bind");
            bindService(intent, myLocalServiceConnection, Context.BIND_AUTO_CREATE);
    
        }
    
        private ServiceConnection myLocalServiceConnection = new ServiceConnection() {
            public void onServiceConnected(android.content.ComponentName name,
                    android.os.IBinder service) {
                MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                        MyServiceActivity.UPDATE_VIEW,
                        "myServiceConnection.onServiceConnected"));
                // 因为 客户端 与 服务 在同一个进程内,这样一来,就可以知道参数 "service"的类型了,也就可以进行显示的强制类型转换了。
                // 而如果 客户端与服务不在同一个进程中的话,那么此处是不可以进行显示强制类型转换的,
                // 因为,通过Debug,可以发现此时传进来的 Service 的类型是 BinderProxy
                MyIBinder myIBinder = (MyIBinder) service;
                bsi = (BindServiceWithIBinder) myIBinder.getService();
                isBound = true;
    
                bsi.download();
            };
    
            public void onServiceDisconnected(android.content.ComponentName name) {
                MyServiceActivity.vh.sendMessage(MyServiceActivity.createMessage(
                        MyServiceActivity.UPDATE_VIEW,
                        "myServiceConnection.onServiceDisconnected"));
                isBound = false;
            };
        };

     下面来看运行效果:

    连续点击两次 Bind Service



      

    从此图中可以看出,bind service 的响应过程。也可以看到,第二次点击时,service 没作任何反应,因为当前 Activity 在第一次点击后就已经跟此service绑定了。

    点击 Unbind Service



     至此,该 service 的生命周期结束,它也会被系统给停掉以回收资源。

    http://rainbow702.iteye.com/blog/1144521

     

  • 相关阅读:
    youcompleteme-Vim补全插件安装
    depthimage_to_laserscan代码解读
    如何创建离线化 mapbox sprite精灵图
    mapbox/node-fontnik工具使用介绍
    跟我学习dubbo-使用Maven构建Dubbo服务的可执行jar包(4)
    跟我学习dubbo-Dubbo管理控制台的安装(3)
    跟我学习dubbo-ZooKeeper注册中心安装(2)
    跟我学习dubbo-简介(1)
    跟我学习dubbo-构建Dubbo服务消费者Web应用的war包并在Tomcat中部署(6)
    跟我学习dubbo-在Linux操作系统上手工部署Dubbo服务(5)
  • 原文地址:https://www.cnblogs.com/622698abc/p/2755081.html
Copyright © 2011-2022 走看看