Binder, Service, Summary of Interprocess Communication Learning

Keywords: Android Java SDK

Use of Local Service and Binder

Local Service and Active communication can be implemented by Binder, inherited in Service first. Binder Implement your own Binder class.

  1. class MyBinder extends Binder {  
  2.       public LocalBindService getService() {  
  3.           return LocalBindService.this;  
  4.       }  
  5.   }  

Then in Service onBind() Return to this Binder Examples.

  1. @Override  
  2.    public IBinder onBind(Intent intent) {  
  3.        Log.i(TAG,"onBind");  
  4.        doSomeTask();  
  5.        return mMyBinder;  
  6.    }  

In Activity, through onServiceConnected() Obtain Binder Examples are from Binder Instances give service instances. This can call public methods in Service, but sometimes it is necessary for Service to notify Activity actively to do some UI updating operations. At this point, we need to define an interface in Service, which can then be used by Service to call back the methods in Activity.

  1. interface ProgressChangeListener {  
  2.         void updateProgress(int value);  
  3.     }  
  4.   
  5.     public void setProgressChangeListener(ProgressChangeListener progressChangeListener) {  
  6.         mProgressChangeListener = progressChangeListener;  
  7.     }  

In Activity:
  1. private ServiceConnection mConnection = new ServiceConnection() {  
  2.         @Override  
  3.         public void onServiceDisconnected(ComponentName name) {  
  4.   
  5.         }  
  6.   
  7.         @Override  
  8.         public void onServiceConnected(ComponentName name, IBinder service) {  
  9.             LocalBindService.MyBinder myBinder = (LocalBindService.MyBinder) service;  
  10.             LocalBindService localBindService =myBinder.getService();  
  11.             //Communicate with Service through Binder  
  12.             localBindService.setProgressChangeListener(new LocalBindService.ProgressChangeListener() {  
  13.                 @Override  
  14.                 public void updateProgress(int value) {  
  15.                     mBindProgressBar.setProgress(value);  
  16.                 }  
  17.             });  
  18.         }  
  19.     };  

Communication with remote processes via Messenger

Messenger enables Service to communicate with remote processes. Messenger All requests in the queue are placed in a single thread, so the Service can only process one request at a time.

1. Service implements a Handler To receive and process messages sent by clients.

  1. class MessengerHandler extends Handler {  
  2.        @Override  
  3.        public void handleMessage(Message msg) {  
  4.            switch (msg.what) {  
  5.                case MSG_REGISTER_CLIENT:  
  6.                    mClients.add(msg.replyTo);  
  7.                    break;case MSG_UNREGISTER_CLIENT:  
  8.                    try {  
  9.                        msg.replyTo.send(Message.obtain(null,  
  10.                                MSG_UNREGISTER_CLIENT, 88880));  
  11.                    } catch (RemoteException e) {  
  12.                        e.printStackTrace();  
  13.                    }  
  14.                    mClients.remove(msg.replyTo);  
  15.                    break;case MSG_SET_VALUE:  
  16.                    mValue = msg.arg1;  
  17.                    for (int i = mClients.size() - 1; i >= 0; i--) {  
  18.                        try {  
  19.                            mClients.get(i).send(Message.obtain(null,  
  20.                                    MSG_SET_VALUE, mValue, 0));  
  21.                        } catch (RemoteException e) {  
  22.                            mClients.remove(i);  
  23.                        }  
  24.                    }  
  25.                    break;default:  
  26.                    super.handleMessage(msg);  
  27.            }  
  28.        }  
  29.    }  

2. Create a reference containing Handler Messenger Object.

  1. private MessengerHandler mMessengerHandler = new MessengerHandler();  
  2.   private Messenger mMessenger = new Messenger(mMessengerHandler);  

3. Pass Messenger Get Binder And from onBind() Method returns it.

  1. @Override  
  2.    public IBinder onBind(Intent intent) {  
  3.        return mMessenger.getBinder();  
  4.    }  

4. In Service Connection, the client uses IBinder To instantiate this Messenger Use this. Messenger Send to Service Message Object, Service Handler will process this Message object in the.http://http://http://http://http://http://http://http://ht

  1. private ServiceConnection mServiceConnection=new ServiceConnection() {  
  2.        @Override  
  3.        public void onServiceConnected(ComponentName name, IBinder service) {  
  4.          mMessengerService=new Messenger(service);  
  5.          mCallbackText.setText("Attached.");  
  6.            try {Message msg = Message.obtain(null,  
  7.                        MessengerService.MSG_REGISTER_CLIENT);  
  8.                msg.replyTo = mMessenger;  
  9.                mMessengerService.send(msg);  
  10.                msg = Message.obtain(null,  
  11.                        MessengerService.MSG_SET_VALUE, this.hashCode(), 0);  
  12.                mMessengerService.send(msg);  
  13.            } catch (RemoteException e) {  
  14.   
  15.            } Toast.makeText(MessengerActivity.this"remote_service_connected",  
  16.                    Toast.LENGTH_SHORT).show();  
  17.        }  
  18.   
  19.        @Override  
  20.        public void onServiceDisconnected(ComponentName name) {  
  21.            mCallbackText.setText("Disconnected.");  
  22.            Toast.makeText(MessengerActivity.this"remote_service_disconnected",  
  23.                    Toast.LENGTH_SHORT).show();  
  24.        }  
  25.    };  

5. The client also defines a Handler object to handle the Message object returned by the server and constructs a handler referenceMessenger Object, when sending a message to the server, the client's Messenger Objects assigned to messagesreplyTo In this way, the server sends the Message object to the client through replyTo.

In this way, the client and the server can pass Message objects to each other.

  1. <span style="font-size:14px;">private Handler mHandler=new Handler(){  
  2.         @Override  
  3.         public void handleMessage(Message msg) {  
  4.             switch (msg.what) {  
  5.                 case MessengerService.MSG_SET_VALUE:  
  6.                     mCallbackText.setText("Received from service: " + msg.arg1);  
  7.                     breakcase  MessengerService.MSG_UNREGISTER_CLIENT:  
  8.                     Toast.makeText(MessengerActivity.this"Received from service: "+msg.arg1,  
  9.                             Toast.LENGTH_SHORT).show();  
  10.                 default:  
  11.                     super.handleMessage(msg);  
  12.             }  
  13.         }  
  14.     };  
  15.   
  16. private Messenger mMessenger=new Messenger(mHandler);</span>  


Communication with remote processes via AIDL

AIDL(Android Interface Definition Language (IDL) is the meaning of Android Interface Definition Language (IDL). It can be used to enable a Service to communicate across processes with multiple application components, thus enabling multiple applications to share the same Service.

If a Service is required to receive multiple requests at the same time, Messenger cannot meet the requirement and needs to use AIDL. In this case, the Service must be able to execute multiple threads and must be thread-safe for the Service.

1. Create a. aidl

AIDL parameters and return values can be of any type, or even other AIDL-generated interfaces. Use Java Language builds a. aidl file, each. aild file must define a separate interface, and use a definite declaration and method signature.

  1. / IRemoteService.aidl  
  2. package com.example.xujiang.servicelearn;  
  3. import  com.example.xujiang.servicelearn.IRemoteServiceCallback;  
  4. // Declare any non-default types here with import statements  
  5.   
  6. interface IRemoteService {  
  7.       void registerCallback(IRemoteServiceCallback cb);  
  8.             
  9.       void unregisterCallback(IRemoteServiceCallback cb);  
  10. }  

2. Inheritance of this interface

The Android SDK tool generates an interface for. aidl files. This interface has an internal abstract class called Stub. You need to write a class that inherits the Stub class and implements these methods, returning instance objects of the class in onBind.

  1. private final IRemoteService.Stub mRemoteServiceStub=new IRemoteService.Stub() {  
  2.         @Override  
  3.         public void registerCallback(IRemoteServiceCallback cb) throws RemoteException {  
  4.            if (cb!=null){  
  5.                mCallbacks.register(cb);  
  6.            }  
  7.         }  
  8.   
  9.         @Override  
  10.         public void unregisterCallback(IRemoteServiceCallback cb) throws RemoteException {  
  11.             if (cb!=null){  
  12.                 mCallbacks.unregister(cb);  
  13.             }  
  14.         }  
  15.     };  

3. Exposing the interface to the client

Inherit a Service and override onBind() to return the implemented Stub class. The client gets the reference of the interface through the asInterface method, so it can call the method in the interface.

If you need to pass classes between processes, classes must support the Parcelable interface. Parcelable interfaces are supported because Android systems need to decompose objects into primitives that can traverse processes.

  1. @Override  
  2.    public IBinder onBind(Intent intent) {  
  3.        Log.i(TAG,"onBind");  
  4.        return mRemoteServiceStub;  
  5.    }  

4. Client Call

  1. private ServiceConnection mConnection = new ServiceConnection() {  
  2.         public void onServiceConnected(ComponentName className,  
  3.                                        IBinder service) {  
  4.             mRemoteService = IRemoteService.Stub.asInterface(service);  
  5.             mCallbackText.setText("Attached.");  
  6.             try {  
  7.                 mRemoteService.registerCallback(mServiceCallback);  
  8.             } catch (RemoteException e) {  
  9.             }Toast.makeText(AIDLActivity.this"remote_service_connected",  
  10.                     Toast.LENGTH_SHORT).show();  
  11.         }  
  12.   
  13.         public void onServiceDisconnected(ComponentName className) {  
  14.             mRemoteService = null;  
  15.             mCallbackText.setText("Disconnected.");  
  16.             Toast.makeText(AIDLActivity.this"remote_service_disconnected",  
  17.                     Toast.LENGTH_SHORT).show();  
  18.         }  
  19.     };  

Posted by wallabee on Mon, 08 Apr 2019 16:15:31 -0700