记录一下通过AIDL调用远程服务的过程,写了一个小demo帮助理解
1、首先新建一个Module作为服务端AIDLService
2、服务端在Java同级目录新建AIDL文件定义服务端提供的方法接口
/home/liuquan/sdb/myCode/TestAIDL_RometServer/AIDLService/src/main/aidl/com/test/aidlservice/IMyAidlInterface.aidl
// IMyAidlInterface.aidl
package com.test.aidlservice;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
String getValue();
}
这个时候Android studio会帮我们自动生成一个Java文件
/home/liuquan/sdb/myCode/TestAIDL_RometServer/AIDLService/build/generated/source/aidl/debug/com/test/aidlservice/IMyAidlInterface.java
这个文件中有一个Stub的内部类
3、在Module中新建一个服务,不要忘了在menifest文件中注册
package com.test.aidlservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;
/**
* Created by liuquan
* on 18-12-20.
*/
public class MyAIDLService extends Service {
private static final String TAG = "liuquanq ";
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, " MyAIDLService onBind: -----------");
return new MyAIDL();
}
private class MyAIDL extends IMyAidlInterface.Stub {
@Override
public String getValue() throws RemoteException {
return "from aidlServer hello world!";
}
}
}
在服务中新建一个内部类继承自IMyAidlInterface.Stub,并实现AIDL中定义的供客服端调用的方法
因为当客户端远程bind这个服务的时候会返回一个IBinder对象,而上一步中工具帮我们生成的IMyAidlInterface中的内部类Stub正是IBinder的子类,所以这个时候我们将我们自己新建的Stub的子类MyAIDL返回。这样客户端连接上我们这个服务后实际会得到MyAIDL对象,通过这个对象就可以调它内部的方法了,也就相当于远程服务跟客户端建立了通信,并传递了数据。
这个时候我们的远程服务就建立完成了,是不是很简单?
4、我们新建一个Module AIDLClent作为客户端去调用远程服务
5、将第2步中新建的AIDL文件IMyAidlInterface.aidl拷贝到AIDLClent中,同样这个时候工具会帮我们生成同样的Java文件。
6、这个时候我们就可以直接在客户端进行调用了
package com.test.testaidl_rometserver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.test.aidlservice.IMyAidlInterface;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "liuquanq";
private IMyAidlInterface iMyAidlInterface;
public ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
Log.d(TAG, "onServiceConnected: iMyAidlInterface = "+iMyAidlInterface);
try {
if (iMyAidlInterface != null) {
String value = iMyAidlInterface.getValue();
mTextView.setText(value);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: intent to bindService-----");
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.text);
Intent intent = new Intent();
intent.setAction("com.test.aidlservice");
intent.setPackage("com.test.aidlservice");
bindService(intent,serviceConnection,Context.BIND_AUTO_CREATE);
}
}
onCreate中我们通过bindService去绑定启动远程服务,因为这种方式我们会用到一个参数就是ServiceConnection,而它不是一个类,而是一个接口,这个时候我们初始化这个接口就需要实现他的抽象方法,其中一个onServiceConnected就是当建立了远程连接之后回调的方法,通过这个方法我们能拿到服务端中的IBinder对象,这样就能够获取到服务端中的数据了。这就是AIDL通信的整个过程。