Android Bound Service(一) ----- Extending Binder Service(进程内绑定Service的简单例子)

ref:http://developer.android.com/guide/components/bound-services.html?

前言
重新学习这一项技术,主要的原因,是因为以前没有好好的学,那时总觉得作品能动,能完成工作就好了,而这种得过且过的想法,大大地影响了我的技术程度,也因此,在这个这个博客里,有许多的复习心得。有幸得到一位前辈的指导,指出,若只是学习,而无实际应用,这样进步会较少,因此,最好要多看源码,并且自己多尝试多实践,这样学习一万小时,应该能有小进步,因此开始了 Bound Service相关学习/复习工作。

Bound Service
「Bound Service是 Client-Server Interface 中的服务端,一个 Activity 可以透过 Bound Service 绑定一个服务,收发讯息,甚至进行进程间通讯。」Service类是一个 Abstract Class,而 Bound Service实现了 Service类,并实现了 onBind()方法,Activity 才能和 Service进行沟通。 所以,我们先从简单的例子--让一个 Activity 绑定一个 Service,让 Service 能够为 Activity 提供服务,同时,我已将练习的相关代码提交至 GitHub上(https://github.com/shanwu/InterProcessCommPractice),有不同的分枝分别代表不同的例子,这样可以使用 Github上的分枝比较功能()比较不同方法间的差异。


master 分枝:进程内通讯,代表的是官网 Extending the Binder class的例子。

ipc_messanger_example:跨进程通讯,代表的是官网 Using a Messenger的例子(抱歉 branch 名英文拼错 Orz)

ipc_messenger_example_bidirection:同上,但是其为 Service, Activity 双向互传的例子。

ipc_aidl_example:跨进程通讯,简单的 aidl 使用例子。


Extending Binder Service
客户端的 Activity 可以透过呼叫 bindService()方法和服务端的 Service建立连结,连结建立的时候,会先调用 Bound Service的 onBind() 方法,再来调用 onServiceConnected(),而如果是需要移除连结的话,便调用 unbindService()方法,此时Bound Service会直接调用 onDestory(),然後服务结束。代码如下:
在Bound Service写一个继承 Binder的类-LocalBinder,主要是在进程内通讯时,在 onBind()的时候,能够用方法来返回 Bound Service的对象:

    public class LocalBinder extends Binder {
        public Service getService() {
            return WorkerService.this;
        }
    }
宣告一个 LocalBinder的私有全局变量
public class WorkerService extends Service {
    private final IBinder mBinder = new LocalBinder();
同时覆写 onBind()方法
    @Override
    public IBinder onBind(Intent intent) {
        Log.d("guang","onBind");
        return mBinder;
    }


而在Activity端,我们需要使用 bindService()来进行绑定 Bound Service的工作

    @Override
    public void onClick(View v) {
        final int id = v.getId();
        switch (id) {
            case R.id.btn_start:
                Intent intent = new Intent(MainActivity.this, WorkerService.class);
                bindService(intent, mServiceConn, Context.BIND_AUTO_CREATE);
                break;

同时我们需要将接口 ServiceConnection的方法覆写,在连结开始的时候,iBinder便是onBind所返回的 IBinder类变量,所以我们将它强转为LocalBinder,然後调用LocalBinder里的方法以取得 Bound Service 的对象,将它在於全局变量中,之後便可以调用他的方法。这边要注意的是 onServiceDisconnected一般情况下不会调用,只有在 Service发生异常导致连结结束才会调用。

        mServiceConn = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                WorkerService.LocalBinder lBinder = (WorkerService.LocalBinder) iBinder;
                mService = (WorkerService) lBinder.getService();
                Log.d("guang","onServiceConnected");
                mIsBind = true;
            }

            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                Log.d("guang","onServiceDisconnected");
                mIsBind = false;
            }
        };
调用它的方法,使 Bound Service 做事,它可以是播放音乐,或是执行其它不需要 UI 界面的工作。
            case R.id.btn_sing:
                if (mIsBind) {
                    mService.makeSingingService();
                }
                break;


这样基本上就是本篇的重点了~全部代码均可自 GitHub取得~

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。