AIDL实现连接服务

Android IPC(三)AIDL实现跨进程通信_跨进程通信

AIDL实现消息服务(客户端→服务端)

Android IPC(三)AIDL实现跨进程通信_IPC通信_02

AIDL实现消息服务(服务端→客户端)

Android IPC(三)AIDL实现跨进程通信_android_03

Demo结构:

大家学习的时候注意要对应上我的Demo结构路径,否则会出现找不到文件的问题,如果你对AIDL文件很熟悉的话,路径可以随自己喜欢选择。

Android IPC(三)AIDL实现跨进程通信_android_04

中间的 IConnectionService、IMessageService等等这块区域的代码是在Android Studio编译时自动生成的

MyBean.aidl

package com.jlink.aidldemo.entity;

//对应java 中的MyBean
parcelable MyBean;

IConnectionService.aidl

package com.jlink.aidldemo;

//连接服务
interface IConnectionService {
//连接
oneway void connect();
//取消连接
void disconnect();
//连接状态
boolean isConnected();
}

IMessageService.aidl

// IMessageService.aidl
package com.jlink.aidldemo;
import com.jlink.aidldemo.entity.MyBean;
import com.jlink.aidldemo.MessageReceiveListener;

//消息服务
interface IMessageService {
//发送消息
void sendMessage(in MyBean myBean);
//注册消息接收监听器
void registerMessageReceiveListener(MessageReceiveListener messageReceiveListener);
//取消注册消息接收监听器
void unRegisterMessageReceiveListener(MessageReceiveListener messageReceiveListener);
}

IServiceManager.aidl

package com.jlink.aidldemo;

interface IServiceManager {
IBinder getService(String serviceName);
}

MessageReceiveListener.aidl

// MessageReceiveListener.aidl
package com.jlink.aidldemo;
import com.jlink.aidldemo.entity.MyBean;

//消息监听器
interface MessageReceiveListener {
void onReceiveMessage(in MyBean myBean);
}

MyBean.java

public class MyBean implements android.os.Parcelable{
private String content; //内容
private boolean isSendSuccess; //状态
public MyBean(){

}

protected MyBean(Parcel in) {
content = in.readString();
isSendSuccess = in.readByte() != 0;
}

public static final Creator<MyBean> CREATOR = new Creator<MyBean>() {
@Override
public MyBean createFromParcel(Parcel in) {
return new MyBean(in);
}

@Override
public MyBean[] newArray(int size) {
return new MyBean[size];
}
};

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(content);
dest.writeByte((byte) (isSendSuccess ? 1 : 0));
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

public boolean isSendSuccess() {
return isSendSuccess;
}

public void setSendSuccess(boolean sendSuccess) {
isSendSuccess = sendSuccess;
}
}

MyService.java

public class MyService extends Service {
private int num = 0;
public MyService(){

}

//RemoteCallbackList 存储 消息监听器
private RemoteCallbackList<MessageReceiveListener> messageReceiveListenerRemoteCallbackList = new RemoteCallbackList<>();
//创建计时器
private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;
//用来注销计时器
private ScheduledFuture scheduledFuture;

@Override
public void onCreate() {
super.onCreate();
scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
}

private Handler handler = new Handler(Looper.getMainLooper());
private boolean isConnected = false;

private IConnectionService connectionService = new IConnectionService.Stub() {
@Override
public void connect() throws RemoteException {
isConnected = true;
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MyService.this,"连接成功",Toast.LENGTH_SHORT).show();
}
});

scheduledFuture = scheduledThreadPoolExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
int size = messageReceiveListenerRemoteCallbackList.beginBroadcast();
num++;
for (int i=0; i<size; i++){
MyBean myBean = new MyBean();
myBean.setContent("喷火龙怒气值:" + num);
try {
//服务端 → 客户端
messageReceiveListenerRemoteCallbackList.getBroadcastItem(i).onReceiveMessage(myBean);
} catch (RemoteException e) {
e.printStackTrace();
}
}
messageReceiveListenerRemoteCallbackList.finishBroadcast();
}
},2000,2000, TimeUnit.MILLISECONDS);

}

@Override
public void disconnect() throws RemoteException {
isConnected = false;
//删除计时器
scheduledFuture.cancel(true);
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MyService.this,"断开连接",Toast.LENGTH_SHORT).show();
}
});
}

@Override
public boolean isConnected() throws RemoteException {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MyService.this,String.valueOf(isConnected),Toast.LENGTH_SHORT).show();
}
});
return isConnected;
}
};

private IMessageService messageService = new IMessageService.Stub() {
@Override
public void sendMessage(MyBean myBean) throws RemoteException {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MyService.this,String.valueOf(myBean.getContent()),Toast.LENGTH_SHORT).show();
}
});

if (isConnected){
myBean.setSendSuccess(true);
}else{
myBean.setSendSuccess(false);
}
}

@Override
public void registerMessageReceiveListener(MessageReceiveListener messageReceiveListener) throws RemoteException {
if (messageReceiveListener != null){
messageReceiveListenerRemoteCallbackList.register(messageReceiveListener);
}
}

@Override
public void unRegisterMessageReceiveListener(MessageReceiveListener messageReceiveListener) throws RemoteException {
if (messageReceiveListener != null){
messageReceiveListenerRemoteCallbackList.unregister(messageReceiveListener);
}
}
};

private IServiceManager serviceManager = new IServiceManager.Stub() {
@Override
public IBinder getService(String serviceName) throws RemoteException {
if (IConnectionService.class.getSimpleName().equals(serviceName)){
return connectionService.asBinder();
}else if (IMessageService.class.getSimpleName().equals(serviceName)){
return messageService.asBinder();
}else {
return null;
}
}
};

@Nullable
@Override
public IBinder onBind(Intent intent) {
return serviceManager.asBinder();
}
}

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btnConnect,btnDisConnect,btnIsConnect;
private Button btnSendMessage,btnRegisterListener,btnUnregisterListener;
private IConnectionService connectionServiceProxy;
private IMessageService messageServiceProxy;
private IServiceManager serviceManagerProxy;

//监听器的实现
private MessageReceiveListener messageReceiveListener = new MessageReceiveListener.Stub() {
@Override
public void onReceiveMessage(MyBean myBean) throws RemoteException {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,myBean.getContent(),Toast.LENGTH_SHORT).show();
}
});
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
Intent intent = new Intent(MainActivity.this,MyService.class);
bindService(intent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
try {
serviceManagerProxy = IServiceManager.Stub.asInterface(iBinder);
connectionServiceProxy = IConnectionService.Stub.asInterface(serviceManagerProxy.getService(IConnectionService.class.getSimpleName()));
messageServiceProxy = IMessageService.Stub.asInterface(serviceManagerProxy.getService(IMessageService.class.getSimpleName()));
} catch (RemoteException e) {
e.printStackTrace();
}
}

@Override
public void onServiceDisconnected(ComponentName name) {

}
}, Context.BIND_AUTO_CREATE);

}

private void init() {
btnConnect = findViewById(R.id.btn_connect);
btnDisConnect = findViewById(R.id.btn_disconnect);
btnIsConnect = findViewById(R.id.btn_is_connected);
btnSendMessage = findViewById(R.id.btn_send_message);
btnRegisterListener = findViewById(R.id.btn_register_listener);
btnUnregisterListener = findViewById(R.id.btn_unregister_listener);
btnIsConnect.setOnClickListener(this);
btnConnect.setOnClickListener(this);
btnDisConnect.setOnClickListener(this);
btnSendMessage.setOnClickListener(this);
btnRegisterListener.setOnClickListener(this);
btnUnregisterListener.setOnClickListener(this);

}

@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_connect:
try {
//连接
connectionServiceProxy.connect();
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.btn_disconnect:
try {
//断开连接
connectionServiceProxy.disconnect();
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.btn_is_connected:
try {
//获取连接状态
boolean isConnected = connectionServiceProxy.isConnected();
Toast.makeText(MainActivity.this,String.valueOf(isConnected),Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.btn_send_message:
try {
//客户端 → 服务端
MyBean myBean = new MyBean();
myBean.setContent("王睿对喷火龙使出了动感光波");
messageServiceProxy.sendMessage(myBean);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.btn_register_listener:
try {
messageServiceProxy.registerMessageReceiveListener(messageReceiveListener);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.btn_unregister_listener:
try {
messageServiceProxy.unRegisterMessageReceiveListener(messageReceiveListener);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}

activity_main.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"
android:gravity="center"
tools:context=".MainActivity">

<Button
android:id="@+id/btn_connect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="连接"/>

<Button
android:id="@+id/btn_disconnect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="取消连接"/>

<Button
android:id="@+id/btn_is_connected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="连接状态"/>

<Button
android:id="@+id/btn_send_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="发送消息"/>

<Button
android:id="@+id/btn_register_listener"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="注册监听器"/>

<Button
android:id="@+id/btn_unregister_listener"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="取消监听器"/>


</LinearLayout>

Demo地址:

链接:https://pan.baidu.com/s/1JHmCOeRIjGaVnwuA8RB2Jw

提取码:u5xh