Binder core mechanism for inter-process analysis Secret was to achieve the principle of

Foreword

Write articles about Binder can not know about it, no start. After reading a lot of excellent article, pick up a pen frightened, afraid of the article is laughable, fear is fraught! Hope you taking the time to read this article while big brother, able skeptical about knowledge of the article, to discuss common progress!
Binder core mechanism for inter-process analysis Secret was to achieve the principle of

First, serialization

Daily development by carrying data Intent Jump Activity, data is typically achieved through Serializable or Parcelable interface before being carried Intent, while Serializable interface and the interface is mainly done Parcelabel object serialization process. The object persistence to the device or the network transmission also need to be serialized.

1.Serializable Interface

Java Serializable interface is provided, the standard sequence and deserialization of an object. Typically an object implements Serializable interface, the object having the ability to be serialized and deserialized, and almost all of work done automatically. SerialVersionID the Serializable interface may be specified is not specified, the effect is used to determine changes in the former sequence and deserialized version of the class occurs. If the values ​​do not match the variable representing certain class property or method has changed, then deserialized problem. (Static member variables and member of the transient keyword tags does not participate in the serialization process)

2.Parcelable Interface

Parcelable Android interfaces are provided, its implementation is relatively complex parity. Object class that implements the interface may be passed in the Intent and Binder.

3. The difference between the two

Serializable is an interface provided by Java, simple to use, but the serialization and de-serialization requires a lot of IO operations, so the overhead is relatively large. Parcelable Android serialization method is provided, cumbersome to use as high efficiency. In Android development, the target sequence or a sequence to the device through the transmission network is recommended Serializable interface, other interfaces Parcelable with recommendations, particularly in the sequence of memory. Binder e.g. Intent and transmit data.

Two, AIDL

In the Java layer, Binder want to use when communicating boast process, it would have by AIDL (Android Interface Definition Language) a, AIDL is between the client and service use interprocess communication (IPC) communicate with each other are recognized programming interfaces, only It allows customers to access services of different applications with IPC end way, and when you want to process multiple threads in a service, only need to use AIDL, if it is in a single application (single-process), it is recommended to use Messager.

1, AIDL supported data types

  • All primitive types in the Java programming language (such as int, long, char, boolean, etc.)
  • String 和 CharSequence
  • All implements the interface objects Parcelable
  • AIDL Interface
  • List, List currently only supports ArrayList type that holds the element must be above mentioned type.
  • Map, currently only supports HashMap type that holds the element must be above mentioned type

Parcelable custom objects and interfaces must display AIDL into AIDL file.

Trend data

Parcelable AIDL objects and interfaces must be marked to the data before using:

  • in the flow of client server
  • out the flow of client server
  • inout service and client can interact

Example:

void addUser(inout User user);

2, the server implementation

2.1, the object definition data
defines a Parcelable implements the interface, as the client and server transmitting data object.

public class User implements Parcelable {

    private String username;

    private String address;

    public User() {
    }

    public User(String username, String address) {
        this.username = username;
        this.address = address;
    }

    User(Parcel in) {
       readFromParcel(in);
    }
    //系统默认生成,反序列化过程,我们只需要要构造方法读取相关值就可以
    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
     //系统默认生成,内容描述功能,几乎所有情况下都返回0,
     //仅仅当前存在文件描述符,才返回1
    @Override
    public int describeContents() {
        return 0;
    }
    //序列化过程,通过一系列的write将值写到Parcel 对象
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(username);
        dest.writeString(address);
    }

    @Override
    public String toString() {
        return username+":"+address;
    }

    public void readFromParcel(Parcel in){
        username=in.readString();
        address=in.readString();
    }
}

2.2, the abstract service server
through the following ways to build a UserManger.aidl documents means that the server can provide any kind of service to clients.
Binder core mechanism for inter-process analysis Secret was to achieve the principle of
The following code is through the establishment of UserManager.aidl file for the client to provide addUserand getUsercapabilities. UserManager can be understood as mutually agreed service and client, and how both can be kind of interaction

package com.gitcode.server;

// 在这里要导入传递对象的类型,例如User
import com.gitcode.server.User;

interface UserManager {

    void addUser(inout User user);

    User getUser(int index);
}

After defining UserManager.aidl file, the system will generate UserManager.java default file.
Binder core mechanism for inter-process analysis Secret was to achieve the principle of
UserManager.java code is as follows, in order to reduce the size, removed some implementations.

public interface UserManager extends android.os.IInterface {

    public static abstract class Stub extends android.os.Binder implements com.gitcode.server.UserManager {
        private static final String DESCRIPTOR = "com.gitcode.server.UserManager";

        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        public static com.gitcode.server.UserManager asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.gitcode.server.UserManager))) {
                return ((com.gitcode.server.UserManager) iin);
            }
            return new Stub.Proxy(obj);
        }

        @Override
        public android.os.IBinder asBinder() {
            return this;
        }

        @Override
        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
           ......
        }

        private static class Proxy implements com.gitcode.server.UserManager {
            private android.os.IBinder mRemote;

            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }

            @Override
            public android.os.IBinder asBinder() {
                return mRemote;
            }

            public String getInterfaceDescriptor() {
                return DESCRIPTOR;
            }

            @Override
            public void addUser(com.gitcode.server.User user) throws android.os.RemoteException {
                 ......
            }

            @Override
            public com.gitcode.server.User getUser(int index) throws android.os.RemoteException {
                .....
            }
        }

        static final int TRANSACTION_addUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_getUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    }

    public void addUser(com.gitcode.server.User user) throws android.os.RemoteException;

    public com.gitcode.server.User getUser(int index) throws android.os.RemoteException;
}

From the above, UserManager itself is an interface and inherit IInterface interface. UserManager.java declared addUserand getUser, in a statement UserManager.aidl and is consistent. At the same time it declares two integers TRANSACTION_addUserand TRANSACTION_getUserfor transact()the method in which the server method to identify the call. If the server and the client calls will go in different processes, methods transact()method, logic performed by Proxy Stub and inner classes.
Internal class Stub some of the concepts and methods meanings:
DESCRIPTOR
uniquely identifies Binder, usually with the current class name full name identification.
asInterface (IBinder obj)
converts the service side of Binder object into a target client AIDL interface type, if the client and server to the same process directly returns Stub object itself, not in the same process, Stub.proxy objects by a system the package is returned
asBinder
returns the current Binder object
onTransact (int code, Parcel data,
Parcel reply, int flags) executed on the server thread pool Binder, when the client requests to initiate cross-process, whereby the system packaging post processing method. code indicate what methods, integer above statement calling the server. data represents data transfer from the client, reply to a reply to the client's server.
Internal proxy class Poxy , showing the operation of the remote server can be a client.
addUser running on the client, when the client remote call,
Created in the same directory User.aidl, it can be copied directly UserManager.aidl content modified as follows.

package com.gitcode.server;

parcelable User;

In the server, the service generally reflect Service, defined UserServcie, inherited Service.

public class UserService extends Service {
    private static final String TAG = "Server";
    private List<User> list = new ArrayList<>();

    @Override
    public void onCreate() {
        super.onCreate();
        list.add(new User("GitCode", "深圳"));
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG,"on Bind");
        return stub;
    }

    private UserManager.Stub stub = new UserManager.Stub() {
        @Override
        public void addUser(User user) throws RemoteException {
            list.add(user);
            Log.i(TAG,"add user:"+user);
        }

        @Override
        public User getUser(int index) throws RemoteException {
            Log.i(TAG,"get user,index:"+index);
            return list.size() > index && index >= 0 ? list.get(index) : null;
        }
    };
}

In AndroidManifest.xml file declares Service, in order to separate the two components form the app to reflect the two processes, data exchange through AIDL. In the client through bindService()to start the service.

<service android:name="com.gitcode.server.UserService"
    android:enabled="true"
    android:exported="true">
        <intent-filter>
            <action android:name="com.gitcode.server.userservice"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
</service>

3, the client implementation

The main client is a request to the server through a common agreement (UserManger.aidl), the server responds to the request of the client. In order to improve efficiency and reduce errors, the client is achieved by copying the file AIDL. Copy the service side of aidl entire file to the client's main directory, without making any changes.
Binder core mechanism for inter-process analysis Secret was to achieve the principle of
User directory and server to establish similar package, and User class copied, without any changes on the client side.
Binder core mechanism for inter-process analysis Secret was to achieve the principle of
Binding Activity in the service side of the Service, the binding is successful for data exchange.

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "Client";
    private UserManager mUserManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toBindService();
    }

    private void toBindService() {
        Intent intent = new Intent("com.gitcode.server.userservice");
        intent.setPackage("com.gitcode.server");
        bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mUserManager = UserManager.Stub.asInterface(service);

            try {
                User user = mUserManager.getUser(0);
                Log.e(TAG, user.toString());

                mUserManager.addUser(new User("张三","北京"));
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };
}

running result:

Client:
Binder core mechanism for inter-process analysis Secret was to achieve the principle of
server:
Binder core mechanism for inter-process analysis Secret was to achieve the principle of

4. Summary

The client calls the service method, method of operation is called the Binder thread pool service side, while the client will be suspended, if the server method to perform time-consuming operation, it will cause the client to ANR, so do not master the client threads access the remote service method. At the same time the server should not create a new thread running their new service method, because the method will be referred to thread pool, while the data should also be made concurrent access to treatment.
AIDL can be said to provide application-layer development package, not too much to understand the mechanisms Binder by UserManager.java generated preliminary Binder can understand the mechanism of IPC. Use AIDL data communication between processes, more attention is the implementation details and operations.

Three, Binder

Binder is an Android IPC mechanism provided by the system. Because Android is based on the Linux kernel, therefore, in addition to Binder, other IPC mechanisms, the Socket e.g., shared memory, message queues, and pipes and the like. All of the original IPC mechanism is not used, because of the use Binder mechanisms, from the performance, stability, security brings better results. For example, Socket is a common interface, the transmission rate is low, such a case suitable for network transmission, while the two pipes, and message queue requires copying of data, it is difficult to control the content sharing and the like. The Binder copy the data only once, using C / S structure, responsibilities clear, easy to maintain and use.
May be learned by the FIG., Binder cross-process communication mechanism through memory mapping, the IPC mechanisms Binder only as a carrier of data, writing data to the virtual memory space when process A, data is real-time feedback to the virtual process B memory space. The entire process of sending data, the user only copied from the primary space into the virtual memory space.
Binder core mechanism for inter-process analysis Secret was to achieve the principle of
In Binder mechanism, mainly related to the three terminals Client, Server, ServiceManger, three cross-process communication by Binder, supporting Android this big network. Their relationship as FIG.
Binder core mechanism for inter-process analysis Secret was to achieve the principle of
Server
Server process needs to register some Service to ServiceManger in order to inform the external services it can provide. AIDL above example, registers UserService, and provides User and add operations to get the User Client. Registration process, Server process is the client and the server is ServiceManger.
Client
to Sever process business logic operations. Find the corresponding Service in ServiceManger by Name Service.
ServiceManager
ServiceManger concentrate all Service within the management system, service Service to ServiceManger lookup table by registering, when the Client requests ServiceManger queries correspond in the lookup table according to the Service Name Service.
The figure shows the three C / S structure, for example, Client query to query ServiceManger Service, Client is a client, and the server is ServiceManger. The dotted lines indicate inter-process communication between the two by Binder, therefore understanding by a dotted line in the process, you can know the mechanism of Binder.

1, the registration process of the Service

Through the registration process Service Server process, you can understand the principle Binder mechanisms.
Binder core mechanism for inter-process analysis Secret was to achieve the principle of
BpServcieManger and BnServcieManger is the client and server processes to achieve business layer editing package, but BpBinder and BBinder is the way IPC mechanisms. Server process at this time is the client, ServiceManger is the server.
1.1 ProcessState
each process by a singleton ProcessState create a unique object constructor in which, by the open_driver()method of opening the / dev / binder device, corresponding to the opened channel Binder Server process driven interaction with the core, and set the maximum support the number of threads is 15. binder device is a virtual Android device in the kernel to complete inter-process communication specifically set.
1.2 BpBinder and BBinder
BpBinder and BBinder are related to Android representatives Binder communicate with both one to one, are derived from IBinder from. If BpBinder behalf of the client, then BBinder on behalf of the server, a BpBinder by interacting handler identity with the corresponding BBinder. Binder in the system, handler identified as 0 represents ServiceManger corresponding BBinder. BpBinder not directly operate with BBinder open ProcessState binder apparatus.
1.3 BpServiceManger and BnserviceManger
both inheritance to IServiceManger, related to the business logic can be said to be the logical architecture business layer to Binder mechanisms. BnserviceManger derived from IServiceManger BBinder come directly participate in the communication Binder, and BpServiceManger point BpBinder by mRemote.
1.4 Related Service registered
by the above three sections, BpServiceManger object implements the business function IServiceManger, but also as a communication BpBinder representatives, following analysis of the process of registration.
Service object name string and passed as parameters BpServiceManger object addService()function, which is passed to the parameter data BpBidner after packing transact()function. This business logic layer ends, the main role is to package the request information to process communication layer.
In BpBinder of transact()function calls IPCThreadState object transact()function, so that in itself was not involved in the interaction BpBinder Binder devices. Each thread has a IPCThreadState object which has a Mout, mIn buffer, used to store and forward data Mout Binder device, and to receive data Binder mIn apparatus. By ioctlinteracting with the way the device Binder.

1.5 Summary

Service through the registration process above, the analysis of the mechanism of Binder. Binder only communication mechanism, the business can be based on Binder mechanism can also be based on other IPC mechanisms manner, that is why there are BpServiceManger above and BpBinder. Binder is complicated by layers of encapsulating Android by clever together with the communication traffic. Mainly design ideal for very fast hardware.

Binder core mechanism for inter-process analysis Secret was to achieve the principle of

2 ServiceManger

By analyzing subsection 1, we should also have a class that inherits from afar BnServiceManger to handle requests it?
It is unfortunate that the server did not respond to the request BnServiceManger subclass remote client, but to the ServiceManger to deal with.
2.1 Service Management Center to become
ServiceManger open binder equipment by binder_open function, and mapped memory. By handler equal to 0 to identify yourself to become a management center, all service registered with the ServiceManger, through the handle is identified as the BpBinder 0 found ServiceManger corresponding BBinder, ServiceManager Service will save the information to be registered, to find convenient Client . Not all of the Service may be registered in ServiceManger, if enough root privileges Server process or system, you need to add an entry to the allowed.
Bring the benefits of centralized management of 2.2 ServiceManger

  • Unified management, the right to exert control
  • Notification string name Find Service
  • Server process impermanence of life, through ServiceManger, Client can know in real time the most dynamic line Server process.

3、Client

Client Service Server you want to use the process provided What steps should we do?
3.1 Query ServiceManger
Client want to get information about a Service, we have to deal with ServiceManager, to obtain information by calling the corresponding Service getService () method. Client Service query corresponding to ServiceManger by service name. If the Service is not registered, the loop waits until the Service Register; If already registered, the package will correspond to a remote Service BpBinder can BpXXXService and communication through the Service, the customer calls the Client related business logic functions.
3.2 processing request information
Client service call function does is to request package sent to Binder driving parameter, BpBinder to find the corresponding handle end Service handler of a value.
In section 1.4, it comes IPCThreadState object executeCommand in its function, by calling to achieve the object onTransact BnServiceXXX function, positioned directly to the business layer. That is, the AIDL why () function processing response data onTransact.

IV Summary

By learning Binder mechanism to understand how Android Binder mechanism through the layers of the package will be integrated to the application, there is a more in-depth understanding of the mechanisms of Binder. Through the use of the Java layer AIDL deepen the understanding of the mechanism of Binder.

Guess you like

Origin blog.51cto.com/14295695/2417572