Messenger source code analysis

Brief introduction: Messenger is a lightweight IPC solution. Its underlying implementation is AIDL, which means that it is a simple package of AIDL for Android to open
 The sender can only process one request at a time for interprocess communication, so thread synchronization is not considered in the server, because there is no concurrent execution in the server.

Next, go to the main topic and start source code analysis

Constructor
There are two constructors in Messenger

    //1. Deliver the Handler to process the request
    public Messenger(Handler target) {
        mTarget = target.getIMessenger();
    }
    //2. This is not commonly used. If you are interested in it, you can study it, so I will not give you a key introduction here
    public Messenger(IBinder target) {
        mTarget = IMessenger.Stub.asInterface(target);
    }

When we use interprocess communication, we need to create a Service on the server side, and hold an instance of Messenger, which is to send messages to the client through this Messenger. See the simple implementation:

public class MyService extends Service {

    private static Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };

    private Messenger messenger = new Messenger(mHandler);
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {

        return messenger.getBinder();
    }
}

send message

   public void send(Message message) throws RemoteException {
        mTarget.send(message);
    }

It can be seen that Messager is actually a proxy class, and the actual operator is mTarget (an instance of IMessenger).

See how mTarget is instantiated

//There is a final method in the Handler class. You can see that our mTarget is instantiated through this method
    final IMessenger getIMessenger() {
        synchronized (mQueue) {
            if (mMessenger != null) {
                return mMessenger;
            }
            mMessenger = new MessengerImpl();
            return mMessenger;
        }
    }

See what MessengerImpl is

    //It's an internal class of Handler. Do you think of AIDL here
    private final class MessengerImpl extends IMessenger.Stub {
        public void send(Message msg) {
            msg.sendingUid = Binder.getCallingUid();
            Handler.this.sendMessage(msg);
        }
    }

Source code appendix:

IMessenger.aidl source code

/* //device/java/android/android/app/IActivityPendingResult.aidl
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/
package android.os;
import android.os.Message;
/** @hide */
oneway interface IMessenger {
    void send(in Message msg);
}

Tags: Android Apache Java

Posted on Thu, 02 Apr 2020 02:10:55 -0700 by renekosterman