Get the proxy object of the server through the bindService method, and then call the method defined in the aidl file. The essential process is the transfer of the binder object, and the binder object of the server is passed to the client through AMS
server side
MathService.aidl
package com.sunday.aidl;
IMathService interface
{
long add(long a, long b);
}
The IMathService.java file will be automatically generated in the gen directory
MathService.java
package com.sunday.aidl;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MathService extends Service
{
public class MathServiceImpl extends IMathService.Stub
{
@Override
public long add(long a, long b)
{
return a + b;
}
}
@Override
public IBinder onBind(Intent intent)
{
return new MathServiceImpl();
}
}
Add service record in AndroidManifest.xml
client side
MainActivity.java
public class MainActivity extends ActionBarActivity implements OnClickListener{
private myConnection serviceConnection = new myConnection();
private IMathService myService = null;
public class myConnection implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
myService = IMathService.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name)
{
}
}
@Override
public void onClick(View view)
{
try {
long ret = myService.add(2017, 1);
Toast.makeText(this,
"The result is " + ret, Toast.LENGTH_LONG).show();
} catch (Exception e) {
// TODO: handle exception
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate (savedInstanceState);
setContentView(R.layout.activity_main);
bindService(new Intent("com.sunday.aidl.IMathService"),
serviceConnection, BIND_AUTO_CREATE);
Button aButton = (Button)findViewById(R.id.button1);
aButton.setOnClickListener(this);
}
View process
1|Unknown:/ # ps | grep aidl
u0_a103 28072 608 1771868 71060 SyS_epoll_ 792c011794 S com.example.aidlclient
u0_a102 28108 608 1715168 46232 SyS_epoll_ 792c011794 S com.sunday.aidl
Each step is a binder communication call
Consecration theory
Study the processing of bindService and verify the opening theory
The server obtains the IBinder object of the user service, and then returns it to the client for use. The client can use it. This is the delivery of the IBinder object.
myServer.cpp
#include <stdio.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/IBinder.h>
#include <binder/Binder.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
using namespace android;
//
sp<IBinder> aBinder = NULL;
class myBinder : public BBinder
{
public:
status_t dump(int fd, const Vector<String16>& args)
{
write(fd, "myBinder dump called ", 22);
return NO_ERROR;
}
status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t /*flags*/)
{
switch (code) {
case DUMP_TRANSACTION: {
printf("dump called\n");
int fd = data.readFileDescriptor();
int argc = data.readInt32();
Vector<String16> args;
for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
args.add(data.readString16());
}
return dump(fd, args);
}
case 2: {
int num = data.readInt32();
printf("onTransact called, case 2, num = %d\n", num);
reply->writeInt32(num * 2);
return NO_ERROR;
}
case 3:{
printf("onTransact called, case 3\n");
reply->writeStrongBinder(aBinder);
return NO_ERROR;
}
}
return NO_ERROR;
}
};
int main ()
{
sp < ProcessState > proc(ProcessState::self());
sp < IServiceManager > sm = defaultServiceManager();
//get service
sp<IBinder> service = sm->checkService(String16("user"));
if (service != NULL) {
printf("get service\n");
thence = service;
}
sm->addService(String16("myService"), new myBinder());
printf("add myService\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
myClient.cpp
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/TextOutput.h>
#include <utils/Vector.h>
#include <binder/BpBinder.h>//
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
using namespace android;
int main(int argc, char* const argv[])
{
sp<IServiceManager> sm = defaultServiceManager();
fflush(stdout);
if (sm == NULL)
{
ALOGE("Unable to get default service manager!");
aerr << "dumpsys: Unable to get default service manager!" << endl;
return 20;
}
Vector<String16> args;
sp<IBinder> service = sm->checkService(String16("myService"));
int err = service->dump(STDOUT_FILENO, args);
if (err != 0) {
aerr << "Error dumping service info: (" << strerror(err)
<< ") " << endl;
}
if (argc <= 1)
{
// printf("argc <= 1\n");
return 1;
}
int num = atoi (argv [1]);
printf ( "num =% d \ n", num);
Parcel data;
Parcel reply;
data.writeInt32(num);
err = service->transact(3, data, &reply, 0);
if (err == NO_ERROR)
{
// reply.setDataPosition(0);
printf("\nget reply \n");
sp<IBinder> sBinder = reply.readStrongBinder();
//The dump method of the user service will be called
sBinder->dump(STDOUT_FILENO, args);
}
return 0;
}
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
myServer.cpp
LOCAL_SHARED_LIBRARIES := \
libbase \
libutils \
liblog \
libbinder
ifeq ($(TARGET_OS),linux)
LOCAL_CFLAGS += -DXP_UNIX
#LOCAL_SHARED_LIBRARIES += librt
endif
LOCAL_MODULE:= bServer
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
myClient.cpp
LOCAL_SHARED_LIBRARIES := \
libbase \
libutils \
liblog \
libbinder
ifeq ($(TARGET_OS),linux)
LOCAL_CFLAGS += -DXP_UNIX
#LOCAL_SHARED_LIBRARIES += librt
endif
LOCAL_MODULE:= bClient
include $(BUILD_EXECUTABLE)
test
Unknown:/data/local/tmp # ./bServer
get service
add myService
dump called
onTransact called, case 3
Unknown:/data/local/tmp # ./bClient 0
myBinder dump called num = 0
get reply
Users:
UserInfo{0:null:13} serialNo=0
Created: <unknown>
Last logged in: +13d1h6m53s828ms ago
The dump method of the user service is executed