Android通过AIDL与远程服务通信

Android的一大特色就是不同进程间的组件间可以相互通信.我们可以通达Intent去调用其它进程的Activity,通过给定的Uri和权限去访问其它应用的数据(ContentProvider),那么一个应用如何调用其它App的Service呢,这时我们的AIDL就派上了用场。通过AIDL,就可以调用远程Service提供的功能。
在讲使用AIDL的时候,首先我们要搞明白,一个Activity如何与Service通信,最常用的也是android系统推荐的就是Binder机制。步骤如下:
1.创建一个Service并实现一个Binder,在Binder中提供要对外暴露的接口方法。
2.Activity通过binder方式去启动一个Service,在Activity中创建一个ServiceConnection.通过ServiceConnection获取到服务返回的Binder对象,从而可以调用Binder中的方法。
这是一个Activity与Service通信的基础。那么与远程Service通信如何实现呢,就是在与本地Service步骤中添加一步定义好AIDL接口文件即可。只要创建一个普通的文件以后缀AIDL结尾即可,这样无论eclispe还是as都会自动帮我们生成一个.java文件。在此AIDL中定义好我们要使用的方法即可。如果涉及到对象数据的传递,对象一定要Pracelable序列化,并提供对象的AIDL文件。
以上就是最基本的与远程服务通信的基础,这时我们可以从远程Service主动的拉取数据了,但如果我们想远程Service一有数据变化就通知我们,而不是我们不停的去拉取数据呢,这时候,我们就要用到远程接口回调了,把我们要实现的操作作为一个AIDL接口,做为参数传递到我们之前定义好的功能性AIDL接口即可。说了这么多,下面我们看一个完整的代码,就明白如何与远程服务器通信并使用推和拉两种不同的方式去获取数据了。
代码如下:
1.AIDL接口定义:

// 功能接口定义
package com.example.guo.myapplication;
import com.example.guo.myapplication.TimerServiceCallback;
interface IAppServiceRemoteBinder {
    void registCallback(TimerServiceCallback callback);
    void unRegistCallback(TimerServiceCallback callback);
}
//客户端回调处理定义
interface TimerServiceCallback {
  void onTimer(int numIndex);
}

2.模拟实现我们的远程Service

public class AppService extends Service {
    private RemoteCallbackList<TimerServiceCallback> callbackList = new RemoteCallbackList<>();
    private boolean running = false;
    public int numIndex;

    @Override
    public IBinder onBind(Intent intent) {
        return new IAppServiceRemoteBinder.Stub() {

            @Override
            public void registCallback(TimerServiceCallback callback) throws RemoteException {
                callbackList.register(callback);
            }

            @Override
            public void unRegistCallback(TimerServiceCallback callback) throws RemoteException {
                callbackList.unregister(callback);
            }
        };
    }

    @Override
    public void onCreate() {
        super.onCreate();
        new Thread() {
            @Override
            public void run() {
                running = true;
                for (numIndex = 0; running; numIndex++) {
                     /**
                      * 通知所有的观察者
                      */
                    int count = callbackList.beginBroadcast();
                    while (count-- > 0) {
                        try {                        callbackList.getBroadcastItem(count).onTimer(numIndex);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                    callbackList.finishBroadcast();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        running = false;
    }
}

3.编写客户端调用代码,主要代码如下:

private ServiceConnection conn = new ServiceConnection(){
@Override
    public void onServiceConnected(ComponentName name, IBinder service) {

        binder = IAppServiceRemoteBinder.Stub.asInterface(service);
        try {
            binder.registCallback(onServiceCallback);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        callUnRegistBinder();
    }
 }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        callUnRegistBinder();
    }

    private void callUnRegistBinder() {
        try {
            binder.unRegistCallback(onServiceCallback);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /**
     * 实现业务逻辑回调方法,每次数据改变,回调此AIDL接口
     */
    private TimerServiceCallback.Stub onServiceCallback = new TimerServiceCallback.Stub() {
        @Override
        public void onTimer(int numIndex) throws RemoteException {
            Message msg = Message.obtain();
            msg.obj = MainActivity.this;
            msg.arg1 = numIndex;
            handler.sendMessage(msg);
        }
    };

欢迎大家关注我的微信公众号,每天会为大家推荐一篇好的技术文章,还有我的视频课程喔
代码下载

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值