? 快速了解AIDL的基本格式,可以快速实现一个通讯流程.以及我在学习中踩得坑.
-
在server model中新建一个IUserService.aidl文件
重点:必须要rebuild project 一下 as会生成一个辅助文件 IUserService.java
package com.example.server;
interface IUserService {
String getUserName();
}
-
service app 中 新建一个Service
public class UserService extends Service {
@Override
public IBinder onBind(Intent intent) {
return binder;
}
IBinder binder = new IUserService.Stub() {
@Override
public String getUserName() {
return "法外狂徒-张三";
}
};
}
-
注册service exported必须要加 允许外部调用 intent-filter添加action标识
<service
android:name=".UserService"
android:exported="true">
<intent-filter>
<action android:name="com.example.server.action" />
</intent-filter>
</service>
-
添加一个默认的空的MainActviity 并注册
-
新建一个client app 并将server中的aidl目录整体copy过来 不要更改包名 直接粘贴过来
-
rebuild project 一下 as会生成一个辅助文件 IUserService.java 等下要使用IUserService.java文件
-
新建一个ServiceConnection 监听service 连接和断开
private IUserService mService;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
Log.d("-----------------", "connect success");
mService = IUserService.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d("-----------------", "error disconnect");
mService = null;
}
};
-
先绑定先 bindservice 然后 可以获取server中的name字段 没啥重点 直接贴代码了
MainActivity.class
public class MainActivity extends AppCompatActivity {
private IUserService mService;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d("-----------------", "connect success");
mService = IUserService.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d("-----------------", "error disconnect");
mService = null;
}
};
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.bind_service:
Intent intent = new Intent();
intent.setPackage("com.example.server");
intent.setAction("com.example.server.action");
boolean a = bindService(intent, conn, Context.BIND_AUTO_CREATE);
Toast.makeText(this, "服务绑定" + a, Toast.LENGTH_LONG).show();
break;
case R.id.get_user_name:
try {
String name = mService.getUserName();
Toast.makeText(this, "从server获取的name是:" + name, Toast.LENGTH_LONG).show();
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
}
MainActivity的xml 没啥特别的 就两个按钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/bind_service"
android:layout_width="match_parent"
android:layout_height="60dp"
android:onClick="onClick"
android:text="绑定服务" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/get_user_name"
android:layout_width="match_parent"
android:layout_height="60dp"
android:onClick="onClick"
android:text="获取信息" />
</LinearLayout>
-
如果你的client端的 targetSdkVersion大约等于30 也就是andorid 11你需要在client的AndroidManifest.xml文件中添加之下代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.client">
<queries>
// 是server的 applicationId 包名
<package android:name="com.example.server" />
</queries>
<application>
...
</application>
</manifest>