Andorid中的AIDL(一)

来源:互联网 发布:南方电网面试 知乎 编辑:程序博客网 时间:2024/04/30 06:47

在工作中会有Android中使用AIDL 绑定Service通信,使用起来也是停留在会用。

读了任玉刚的书《android开发艺术探索》后也是一知半解,还是做一个Demo来对着书分析一下吧。

这篇先做一个AIDL通信Demo,备忘一下搬运过程。

1)建立两个Module,一个是客户端App,一个是服务端serverapp


同时在俩个Module中建立两个AIDL文件夹,并且建立aidl文件如下

package com.xue.qin.aidl;interface IMyAidlInterface {    String getCurrentTime(int which);}

这里的包名和aidl文件的名字和aidl文件的内容要保证完全一致。

这个Aidl文件会在如下图的位置生成一个java文件,具体的等下一篇继续分析。

(甚至可以吧aidl文件删掉,把这个java文件可以拷贝到通aidl文件相同包中使用)


2)服务端开启服务,在serverapp中建立一个Service对外提供服务manifest中注册此服务。

        <service android:name=".ServerService">            <intent-filter>                <action android:name="remoteService"></action>            </intent-filter>        </service>

在server中建立放回的BInder,具体的下篇继续分析。

private class MyBinder extends IMyAidlInterface.Stub{        @Override        public String getCurrentTime(int which) throws RemoteException {            String result="";            switch (which){                case 0:                    SimpleDateFormat sdf = new SimpleDateFormat("", Locale.SIMPLIFIED_CHINESE);                    sdf.applyPattern("yyyy年MM月dd日 \nHH时mm分ss秒");                    result = sdf.format(System.currentTimeMillis());                    break;                case 1:                    result = "开机之后过去了\n "+formatTime(SystemClock.elapsedRealtime());                    break;                case 2:                    //SystemClock.uptimeMillis() 去掉休眠的时间                    result = "实际使用了\n" +formatTime(SystemClock.uptimeMillis());                    break;            }            return result;        }    }

自定义个MyBinder 继承自IMyAidlInterface的内部类stub(就是第一步自动生成的那个java文件),重写接口getCurrentTime()方法,以提供给客户端调用。

@Override    public IBinder onBind(Intent intent) {        return new MyBinder();    }
重写onBind()并且返回一个MyBinder()

3)客户端绑定服务,app要访问这个服务端就要先与其建立绑定。

 Intent intent = new Intent("remoteService");        intent.setPackage("com.xue.qin.server");        boolean success = bindService(intent, mConntection, Context.BIND_AUTO_CREATE);

因为不是在同一个进程里,intent要设置服务端的包名才行,然后调用bindService这个函数,参数分别 

Intent:请求Intent

ServiceConnection:绑定状态回调

flags:启动的方式 Context.BIND_AUTO_CREATEb表示如果Service没有启动那么就创建并启动它。

返回值 如果绑定成功返回true 失败返回false

第三个参数需要新建一个ServiceConnection接口如下:

private ServiceConnection mConntection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            Log.i(TAG, "onServiceConnected()");            mService = IMyAidlInterface.Stub.asInterface(service);            mHandler.post(mRunable);        }        @Override        public void onServiceDisconnected(ComponentName name) {            Log.i(TAG, "onServiceDisconnected()");            mService = null;        }    };
这里当绑定成功时onServiceConnected()会被回调,

a、这里的IBinder service 这个参数service就是在服务端返回的Mybinder;

声明这个Aidl接口来接受这个返回值,其中IMyAidlInterface mService;

mService = IMyAidlInterface.Stub.asInterface(service);

b、当绑定断开时onServiceDisconnected()会被回调。

拿到这个返回的接口之后,就可以在客户端调用服务端的回调了。

mService.getCurrentTime(mCount%3)


最后使用,要先安装服务端,然后就可以把服务端退掉了。


再安装客户端运行效果如下。


demo地址  https://github.com/xueqin123/repository1

原创粉丝点击