为了实现不同间进程通信,我们会使用到AIDL。 由服务端提供服务,客户端通过AIDL链接服务端,以调用服务端对应的功能。

1.服务端

先来看服务端的代码。 我们在Java同级目录下,新建一个aidl文件夹,然后在该文件夹下,新建一个路径和工程包名同样的路径。路径创建完成后,新建AIDL文件。

1.1 AIDL

AIDL文件是Interface类型,我们只要在里面写好对应的方法即可。这里我们做一个简单的加减法运算。

// IMyAidlInterface.aidl

package com.example.aidlserver;

// Declare any non-default types here with import statements

interface IMyAidlInterface {

int add(int num1,int num2);

int getNum();

int minus(int num1,int num2);

}

AIDL文件写好之后,通过IDE进行编译,以便IDE生成对应的文件:app/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out/com/example/aidlserver/IMyAidlInterface.java

1.2 Service

接下来看Service写法:

public class IRemoteService extends Service {

private static final String TAG = "IRemoteService";

private int i = 0;

@Nullable

@Override

public IBinder onBind(Intent intent) {

return iBinder;

}

private IBinder iBinder = new IMyAidlInterface.Stub() {

@Override

public int add(int num1, int num2) throws RemoteException {

return num1 + num2;

}

@Override

public int getNum() throws RemoteException {

return i;

}

@Override

public int minus(int num1, int num2) throws RemoteException {

return num1 - num2;

}

};

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

new Thread(new Runnable() {

@Override

public void run() {

while (true) {

i++;

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

Log.d(TAG, "i: " + i);

}

}

}).start();

return super.onStartCommand(intent, flags, startId);

}

}

创建好service类之后,会要求我们复写onBind方法,该方法返回值是一个IBinder。这个IBinder即是我们通过AIDL文件生成的:new IMyAidlInterface.Stub()。生成的IBinder文件,传递给onBind方法。

1.3 AndroidMainFest

写好Service ,记得在AndroidMainFest中声明。

package="com.example.aidlserver">

android:name=".IRemoteService"

android:exported="true">

这里注意两点

Service要声明android:exported属性为true,否则其他进程无法访问到该服务。要给Service声明一个action,其他进程会通过该action和Service进行链接。Action我们可以选择 包名+Service名

1.4 Activity

AIDL写好了,服务写好了,启动服务即可。 启动服务可在Activity中进行,也可以在Application中进行。

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

startService(new Intent(this, IRemoteService.class));

}

}

至此服务端的工作全部完成。

2. 客户端

和服务端一样,客户端下,也要先在和java平级路径下新建一个aidl文件夹,然后建立和服务端一模一样的路径,和服务端一模一样的aidl文件。其实就是把服务端的AIDL文件完全复制过来。

2.1 AIDL

和服务端一模一样

// IMyAidlInterface.aidl

package com.example.aidlserver;

// Declare any non-default types here with import statements

interface IMyAidlInterface {

int add(int num1,int num2);

int getNum();

int minus(int num1,int num2);

}

2.2 Activity

客户端链接AIDL。 首先我们绑定服务的Service。创建一个Intent,设置好Package和Action,Package即服务端的包名,Action即服务端AndroidMainFest中声明的action。在新建一个ServiceConnection,当服务链接成功后,我们实例化AIDL接口文件IMyAidlInterface.Stub.asInterface(service)。

private IMyAidlInterface iMyAidlInterface;

private ServiceConnection serviceConnection;

private void initEvent() {

serviceConnection = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);

}

@Override

public void onServiceDisconnected(ComponentName name) {

iMyAidlInterface = null;

}

};

}

private void bindService() {

Intent intent = new Intent();

intent.setPackage("com.example.aidlserver");

intent.setAction("com.example.aidlserver.IRemoteService");

bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

}

实例化iMyAidlInterface后,即可调用对应的方法。

btAdd.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

try {

int res = iMyAidlInterface.add(2, 2);

Log.d(TAG, "add: " + res); //add: 4

} catch (RemoteException e) {

e.printStackTrace();

}

}

});

完整代码:

public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";

private Button btAdd, btMinus, btGet;

private IMyAidlInterface iMyAidlInterface;

private ServiceConnection serviceConnection;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

@Override

protected void onResume() {

super.onResume();

initView();

initEvent();

bindService();

}

private void initView() {

btAdd = findViewById(R.id.add);

btMinus = findViewById(R.id.minus);

btGet = findViewById(R.id.get_number);

btAdd.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

try {

int res = iMyAidlInterface.add(2, 2);

Log.d(TAG, "add: " + res); //add:4

} catch (RemoteException e) {

e.printStackTrace();

}

}

});

btMinus.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

try {

int res = iMyAidlInterface.minus(9, 2);

Log.d(TAG, "minus: " + res); //minus:7

} catch (RemoteException e) {

e.printStackTrace();

}

}

});

btGet.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

try {

int res = iMyAidlInterface.getNum();

Log.d(TAG, "get: " + res);

} catch (RemoteException e) {

e.printStackTrace();

}

}

});

}

/**

* 实例化AIDL

*/

private void initEvent() {

serviceConnection = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);

}

@Override

public void onServiceDisconnected(ComponentName name) {

iMyAidlInterface = null;

}

};

}

/**

* 绑定服务

*/

private void bindService() {

Intent intent = new Intent();

intent.setPackage("com.example.aidlserver");

intent.setAction("com.example.aidlserver.IRemoteService");

bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

}

@Override

protected void onDestroy() {

super.onDestroy();

unbindService(serviceConnection);

}

}

推荐链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。