[Android] Binder object transfer example

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

 

Guess you like

Origin blog.csdn.net/aaajj/article/details/105870608