近期忙着银联支付接口的对接,银联支付的接口采用的 AIDL 进行通讯。那么我就和大家一起分享 AIDL 是如何使用的? AIDL 的全称为 Android Interface Definition Language ,接口描述语言。主要用于进程之间的通讯 新建service项目,新建AIDL文件我这里使用的工具是 Android Studio ,新建 service 项目,我这里的包名是 com.github.service ,以 Packages 为目录结构,如下图新建 IRemoteService.aidl 文件:
// IRemoteService.aidl package com.github.service; // Declare any non-default types here with import statements interface IRemoteService { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); //aidl支持的参数类型有int long boolean float double String } AIDL支持下列所述的数据类型:
接着在接口中添加方法: interface IRemoteService { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); //简单测试获取返回值 String baseAidl(); } 然后点击预编译按钮:
则 AIDL 文件生成对应的 Java 文件, 可以在 build/generated/source/aidl/debug 目录下找到这些 Java 文件。可以看到其内部有一个静态抽象类 Stub ,这个Stub 继承自 Binder 类,并抽象实现了其父接口,这里对应的是 IRemoteService这个接口: public static abstract class Stub extends android.os.Binder implements com.github.service.IRemoteService 新建RemoteService服务在 Java 目录下新建 RemoteService 类:
package com.github.service; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.support.annotation.Nullable; /** * Created by Administrator on 9/19 0019. */ public class RemoteService extends Service { private IRemoteService.Stub mIRemoteService = new IRemoteService.Stub() { @Override public String baseAidl() throws RemoteException { return "你好啊,我是小智!"; } @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } }; @Nullable @Override public IBinder onBind(Intent intent) { return mIRemoteService.asBinder(); } } RemoteService 继承 Service ,在 onBind 方法中返回 IBinder 实例 一定不要忘记在 AndroidManifest.xml 清单文件中配置: <service android:name=".RemoteService" android:process=":remote"> <intent-filter> <action android:name="com.github.service.RemoteService"></action> </intent-filter> </service> 绑定服务Intent intent = new Intent(this, RemoteService.class); bindService(intent, new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { IResultReceiver.Stub.asInterface(service); Toast.makeText(MainActivity.this, "发送成功!", Toast.LENGTH_SHORT).show(); } @Override public void onServiceDisconnected(ComponentName name) { } }, BIND_AUTO_CREATE); 调用 bindService 方法进行服务的一个绑定 新建Client项目进行通讯复制 Service 项目下的 aidl 目录到 Client 的 main 目录下:
当然你新建目录也是可以的,需要注意的是: aidl文件下的包名。 下面来看看 aidl 接口是怎么调用的: package com.github.client; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.github.service.IRemoteService; public class MainActivity extends AppCompatActivity { private IRemoteService mIRemoteService; private TextView tv; private Button bt; private static final String ACTION="com.github.service.RemoteService"; private static final String PACKAGE="com.github.service"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); bt = (Button) findViewById(R.id.bt); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { if (mIRemoteService != null) { String text = mIRemoteService.baseAidl(); if (text != null) { tv.setText(text); } }else { tv.setText("没有获取到服务器发送来的消息"); } } catch (RemoteException e) { e.printStackTrace(); } } }); } @Override protected void onResume() { super.onResume(); Intent service = new Intent(); service.setAction(ACTION); service.setPackage(PACKAGE); bindService(service, new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { mIRemoteService = IRemoteService.Stub.asInterface(iBinder); } @Override public void onServiceDisconnected(ComponentName componentName) { } }, BIND_AUTO_CREATE); } } 注意setAction是与service清单文件的action相匹配的,5.0以上的系统需要加上:service.setPackage(PACKAGE); 运行起来,我们一起来看看: (责任编辑:好模板) |