什么是AIDL?
AIDL是
Android Interface definition language的缩写,它是一种
Android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口
AIDL可以解决什么问题?
- 可以实现多个应用程序共享同一个Service的功能,比如:IM服务可以提供给多个APP使用,先在推送基本都是采取这种方案
- 可以跨进程调用服务里的方法
搭建了简单的Service框架
1.继承Service
public class PushService extends Service{ @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } }
2.在AndroidManifest.xml里注册
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="name.quanke.aidldemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:name=".App"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service
android:name=".PushService"
android:enabled="true"
android:process=":push"
android:exported="true">
</service>
</application>
</manifest>
|
建立AIDL
创建AIDL文件
编写AIDL文件
interface IHandler { void connect(); }
aidl生成后的样子
编写客户端 ServiceConnection
public class PushClient { private IHandler iHandler; private static PushClient instance = new PushClient(); public static PushClient getInstance() { return instance; } public void init(Application app){ Intent binderIntent = new Intent(app,PushService.class); app.bindService(binderIntent, serviceConnection, Context.BIND_AUTO_CREATE); } private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iHandler = IHandler.Stub.asInterface(service); //连接成功调用 } @Override public void onServiceDisconnected(ComponentName name) { //断开连接调用 } }; //通过AIDL远程调用 public void connect(){ try { iHandler.connect(); } catch (RemoteException e) { e.printStackTrace(); } } }
写服务端实现connect方法
public class LibHandler extends IHandler.Stub{ @Override public void connect() throws RemoteException { } @Override public IBinder asBinder() { return null; } }
测试
public class MainActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); init(); } private void init() { findViewById(R.id.aidl_test).setOnClickListener(this); } @Override public void onClick(View view) { PushClient.getInstance().connect(); } }
其实到这里我们就结束了。
接下来我们看看如果自定义传递的数据类型
传递自定义的类型
AIDL默认支持的类型包括Java基本类型(int、long、boolean等),和(String、List、Map、CharSequence),如果要传递自定义的类型需要实现android.os.Parcelable接口。
自定义Message实体:
public class Message implements Parcelable { private long id; private String content; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "Message{" + "id=" + id + ", content='" + content + '/'' + '}'; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeLong(this.id); dest.writeString(this.content); } protected Message(Parcel in) { this.id = in.readLong(); this.content = in.readString(); } public static final Creator<Message> CREATOR = new Creator<Message>() { @Override public Message createFromParcel(Parcel source) { return new Message(source); } @Override public Message[] newArray(int size) { return new Message[size]; } }; }
修改IHandler
interface IHandler { void connect(); void sendMessage(Message message); }
注意: 自定类型aidl文件名字、路径需要和自定义类名字、路径保持一致,
编译一下,发现报了个错
意思是必须定义Message的方向,AIDL 参数有方向。(学习了)
如果
sendMessage方法的message参数是纯粹的输入参数—这意味着是从客户端到服务器的数据,你需要在AIDL声明:
void sendMessage(in Message message);
如果
sendMessage
方法的
message
参数是纯粹的输出-这意味着它的数据是通过从服务器到客户端,使用:
void sendMessage(out Message message);
如果
sendMessage
方法的
message
参数是输入也是输出-客户端的值在服务可能会修改,使用:
void sendMessage(inout Message message);
我们这里是客户端范围服务端的数据,所以用in
interface IHandler { void connect(); void sendMessage(in Message message); }
好了,aidl的用法就到这里了,aidl主要是用在跨进程间通信和数据交换,平时开发中也用的比较少,通过这个例子加深了对他的用法,后面有什么好的坑,我会发出了的,谢谢大家。最后做个链接
https://github.com/xiangzhihong/aidl
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/5986.html