AIDL的全称为 Android Interface definition language 是android接口定义语言。 他的好处是什么 : 进程间通讯 通过 bindService将ServiceConnection进行绑定连接,调用其它线程的功能。
@Override public boolean bindService(Intent service, ServiceConnection conn, int flags) { return mBase.bindService(service, conn, flags); }首先我们在客服端要创建.aidl文件。 第一步:在android studio 工程中new ->AIDL->AIDL File 便可创建出一个.aidl文件命名为IServise.aidl当然这个名字自己随便取但一定要以I开头。如下:
然后再再.aidl文件中写自己需要调用的方法。如下: // IServise.aidl package com.example.yuchao.hellohaha; // Declare any non-default types here with import statements interface IServise { //这里的方法统一不能有修饰符; void callback(); }第二步:在工程中 Build->Make Project 我们会看到在工程的build文件中会生成一个与IServise同名的java文件。 打开IServise.java文件会发现:
通过图片我们可以知道,IServise.Stub.asInterface(Binder obj)方法可以得到IServise的引用,那么他就可以调用IServise接口中的callback()方法。
第三步我们要创建服务端的Service,并且需要声明一个意图(为了其它应用调用)
<service android:name=".service.ServiceDemo"> <intent-filter> <!--这里的意图要与客服端的保持一致--> <action android:name="com.yc.service"/> </intent-filter> </service> public class ServiceDemo extends Service { private static final String TAG = ServiceDemo.class.getSimpleName(); IServise.Stub aidl = new IServise.Stub() { @Override public void callback() throws RemoteException { carryMoney(); } }; @Nullable @Override public IBinder onBind(Intent intent) { return aidl; } private void carryMoney() { Log.d(TAG, "carryMoney: money"); } }第四步将客服端的整个aidl文件夹(记住时整个文件夹)拷贝到服务端的main目录下与java文件夹同级别,
因为aidl通讯要保证.aidl文件的位置在各自的应用中一致。 如图: 第五步:我们就可以在客服端调用AIDL了。调用时最关键的一步 许多网上的写法都是这样写:
ServiceConnection con = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mIServise = IServise.Stub.asInterface(service); try { mIServise.callback(); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; private void initView() { Intent intent = new Intent("com.yc.service"); bindService(intent, con, Service.BIND_AUTO_CREATE); }但运行之后会报 Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.yc.service }参数异常。 这是为什么? 因为在android5.0版本以后,service intent必须为显式指出。 解决方法:
Intent intent = new Intent("com.yc.service"); intent.setPackage("com.example.bankman.service"); bindService(intent, con, Service.BIND_AUTO_CREATE);再次运行就不会有问题了