Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

table of Contents

  1. Foreword
  2. Why use multiple processes?
  3. Why "cross-process communication"?
  4. Inter-process communication options?
  5. Use AIDL implement a multi-process message push
  6. Realization of ideas
  7. Examples of specific implementation
  8. Know, I know why.
  9. Cross-process callback interface
  10. DeathRecipient
  11. Permission Validation
  12. Depending on the process, do different initialization
  13. to sum up
  14. Epilogue

Why use multiple processes

  • For the concept of the process, we are programmed to Cultivation of the people here, without more ado, I believe we backwards, jumping, lying down, a variety of positions can back out.
  • I believe that many students in the actual development, basic will not go to the app division process, and that the use of multiple processes in Android, also may need to write extra code for interprocess communication, it may also bring additional Bug, which undoubtedly increased development effort, in many start-up companies in the construction period is not allowed, which led to the entire app in one process.

The whole app in a process have any drawbacks?

  • In Android, the virtual machine to run the memory allocated to each process is limited value (this value can be 32M, 48M, 64M, etc., according to the model), Imagine if in the app, add a very common picture selection module for uploading pictures or avatars, will be loaded rapidly increase the number Bitmap app's memory footprint, if you also viewed image cache in memory, then OOM risk will increase, if at this time need to use WebView page to load a wave, I asked you afraid!

How micro-channel, microblogging and other mainstream app is to solve these problems?

  • Micro-channel mobile development team "Android memory optimization Zatan" in an article on said: "For the webview, galleries, etc., because of the memory system leak or take up too much memory problems, we can separate process using micro-channel current will put them. in a separate process tools. "

Below we look at using adb process information and micro-channel micro-Bo (Android 5.0 or lower can be directly - see "Settings> Applications" related entries):

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

After entering the adb shell, use "ps | grep Item Name" can be filtered out of the process you want to view.

  • Can be seen, micro-channel does have a tools process, while Sina Weibo also related to the process image, but of them have yet many other processes, such as push the process of micro letter, microblogging remote processes, etc., where you can see them not just the above WebView, gallery, etc. into a separate process, as well as push service is run in a separate process.

  • A message push service, in order to ensure stability, and may require separate UI process, even after the separation UI process exits, Crash or memory consumption is too high and so is the case, does not reduce push messaging.

Visible, the rational use of multiple processes is not just a problem of much benefit, but I personally think it is necessary.

So, we'd better according to their own circumstances, to consider whether to split the process. This is also the original intention of this paper: to provide a reference for everyone's idea of ​​a multi-process, in the face of the above-mentioned problems and scenarios, consider using multi-process method to solve the problem, or, in the interview, with the interviewer to talk this knowledge when you will not be embarrassed.

Why "cross-process communication."

  • Between Android processes and process communication, some of us do not need to write additional code for communication, for example: to select the picture modules into separate processes, we can still use startActivityForResult method, the selected pictures into the Bundle, a transfer that is Intent can. (See here, you're not going to put pictures of your project selection process it to get independence?)

  • But for the "Message Service push" into a separate process, it is slightly more complicated this business, and this time may be a series of complex operations with Service Activity passing objects, call the Service methods occur.

  • Since each process runs in a relatively independent memory space, so they can not communicate directly, because the variables in the program, and other objects are initialized with a memory address, give a simple example, read the value of a variable nature It is to find the memory address of a variable, remove the value stored.

  • Different processes running in memory independent of each other (in fact, it can be understood as two different applications), obviously can not direct that the other variables, the memory address of the object, so naturally can not access each other's variables, objects, and so on. At this time, the two processes interact, we need to use to achieve inter-process communication. Simply put, it is a way for inter-process communication technology can be interaction between processes and processes.

Cross-process communication which

  1. Four component is passed between the Bundle;
  2. Use file sharing, multi-process the same read and write a file, get the file content to interact;
  3. Use Messenger, a lightweight cross-process communications program, using the underlying AIDL achieved (relatively simple to achieve, before the start of this article bloggers also thought about whether to say about this thing, it still think it is not necessary, Google will be able to look at problem-solving, not long-winded);
  4. Use AIDL (Android Interface Definition Language), Android interface definition language for the interface definition cross-process communication;
  5. Use ContentProvider, commonly shared data in multiple processes, such as the system of photo albums, music and so on, we also can be accessed via ContentProvider;
  6. Socket used to transfer data.
  • The next article will focus on the use of AIDL multi-process communication, because AIDL Android is available to our standard cross-process communication API, very flexible and powerful (seemingly also often ask to interview, but not many really used ...) . Messenger is the above mentioned process using a cross-way AIDL implemented, Messenger name suggests, is like a kind of serial message mechanism, it is a lightweight IPC program, you can pass Message objects in different processes, we need to pass into the Message data can easily achieve inter-process communication.
  • But when we need to call the server method, or the presence of concurrent requests, then the Messenger is inappropriate. And transmitting the Bundle of four components, you do not need to explain this, the data needs to be passed, with the Intent to encapsulate transmission, otherwise outside the scope of this paper.

The following began to explain to AIDL, distinguished fellow crossing the robbery ready yet?

AIDL using inter-process messages using a push

Like the picture choose such a multi-process requirements, may not need to write additional code that our communication process, the use of the four components of the transmission Bundle on the line, but like push service this demand, requires a high degree of interaction between the process and the process at this time but it is interprocess communication around this step. Here we use instant messaging software, for example, to implement a multi-process manually push example, specific requirements are as follows:

  1. UI and messages pushed Service in two processes;
  2. UI process for displaying a specific message data, the message sent by the user, the message is transmitted to the Service, and then sent to a remote server;
  3. Service is responsible for sending and receiving messages, and maintain a long connection and the remote server, UI process can send a message through the Service to a remote server, the remote server Service received message notification UI process;
  4. Even if the UI process exits, Service still needs to keep running, you receive the message server.

Realization of ideas

First sort out the realization of ideas:

  1. UI creation process (hereinafter referred to as the client);
  2. Create a Message Service (hereinafter referred to as the server);
  3. The server configuration to a separate process (process specified in the AndroidManifest.xml label);
  4. The client and server bind (bindService);
  5. Let the client and server have the ability to interact. (Using the AIDL);

Examples of specific implementation

For ease of reading, the code will be omitted hereinafter non-priority section, you can put the complete code for this article to the local look Clone article:

https://github.com/V1sk/AIDL

Step0. AIDL call Process Overview

Before we begin, let's recap the entire process using multi-process calls AIDL:

  1. Clients use bindService method to bind the server;
  2. Binder object server returns onBind method;
  3. The client got Binder object returned by the server inter-process method call;

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

To sum up the whole process AIDL call on the above three steps, we use the following example described above, these stepwise decomposition step, and about the details.

Step1. The client server binding method using bindService

1.1 create client and server, the server configuration to another process

  1. Creating Client -> MainActivity;
  2. Create a server -> MessageService;
  3. The server configuration to another process -> android: process = ": remote"

The above-described client, server, and the server process to another configuration, embodied in AndroidManifest.xml, as follows:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Open multi-process method is very simple, just give the four components in the specified android: process tag.

1.2 Binding MessageService to MainActivity

Creating MessageService:

MessageService appearance at this time is just created, onBind returned a null, the next step we will return to an operational object to the client.

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

The client MainActivity call bindService method binding MessageService

This step is actually a part of knowledge related to the Service component, where it is relatively simple to talk about, you can start the service in two ways:

  1. 使用bindService方法 -> bindService(Intent service, ServiceConnection conn, int flags);
  2. Method using startService -> startService (Intent service);

bindService & startService difference: Use bindService way, you can simultaneously bind a multiple Client Service, but when all Client unbind, Service exits, usually, if you want to interact and Service, bindService generally used method, using IBinder objects in onServiceConnected you can interact and Service, and the case does not need to interact Service, startService method to use.

As mentioned above, we are going to interact with the Service, so we need to use bindService method, but we want to keep running after unbind Service, under such circumstances, you can call bindService startService and at the same time (such as in this case the message service exit UI process, Service still need to receive the message), as follows:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Stpe2. Binder object in the server returns the method onBind

2.1 First of all, what is a Binder?

Binder would say, first of all to say about IBinder this interface, IBinder is the base interface, lightweight core of the remote procedure call mechanism remote object, this interface describes the abstract protocol for interacting with remote objects, while Binder implements the interface IBinder , simply, Binder is the Android SDK built a multi-process communication implementation class, when in use, we do not go to achieve IBinder, but this class can inherit Binder multi-process communication.

2.2 Second, the need to return in onBind method Binder object come from?

Here we must leads to the theme of the article --AIDL Binder object is used in multi-process, generally good .adil interface file is automatically generated by our definition, of course, you can go wild ways, this inter-process communications needed to write direct manual the Binder class, its essence is nothing more than a class that inherits Binder, in view of the wild ways go up trouble, and are repeat steps work, Google provides AIDL interfaces to help us automatically generate Binder this the right way, we focus on the following AIDL this right way to continue discussions (not regard people with migraine to the right)

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

2.3 Definitions AIDL Interface

Obviously, we need to engage the next wave of above said Binder, so that clients can call to the server method, and this Binder is automatically generated by AIDL interfaces, then we start AIDL huh, do take a look before precautions to avoid an accident:

AIDL supported data types:

  • All elementary data types (e.g., int, long, char, boolean, etc.) Java programming language
  • String and CharSequence
  • Parcelable: Parcelable object that implements the interface
  • List: wherein AIDL element to be supported, the other end of the particular class is always the ArrayList actually received, but the method used is to generate the interface List
  • Map: wherein AIDL element to be supported, comprising a key and a value, the other end of the concrete classes actually received is always a HashMap, but the method used is generated Map interface

Other considerations:

  • AIDL objects passed in must implement Parcelable serial interfaces;
  • Object passed in AIDL, it is necessary in the same class file path, created with the same name, but the suffix .aidl file and use parcelable keyword to declare the class in a file;
  • With the difference between ordinary interface: You can only declarative approach, can not declare variables;
  • All non-base data type parameters need to be shown the direction of data to tag. It can be in, out or inout, the underlying data type by default only in, not other direction.

Let's continue our example, we began to explain to AIDL of ~

2.4 Create a AIDL interface, the interface provides a method to send a message (Android Studio created AIDL: Right Project -> New -> AIDL -> AIDL File), code is as follows:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

A rather awkward thing, read many articles, one can never say clearly in, out, inout significance of these three parameters directions, later found to understand the answer on StackOverflow ( https://stackoverflow.com/questions/ 4700225 / inout-inout-in- a-aidl-interface-parameter-value), ** I translate what probably meant : **

  • Is "in" marked parameters, parameter is the actual data is received, the parameters passed to us as ordinary meaning. In AIDL in, "out" parameter that specifies only for output, in other words, this argument does not care what data the caller passed over, but the values ​​of the parameters can be called after filling (whether the caller method What value passed over, when the method of execution, the initial value of this parameter is always empty), which is "out" meaning only for output.
  • And "inout" obviously "in" and "out" fit the parameters input and output. Distinction "in", "out" what's the use? This is very important, because the content of each parameter must grouping (serialization, transmission, reception and deserialization). in / out Binder skip tag allows grouping step to obtain better performance.

Above MessageModel entity message class, the class AIDL passed in sequence achieved Parcelable interfaces, as follows:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Parcelable manually implement the interface too much trouble, Amway AS automatically generate a plug-android-parcelable-intellij-plugin MessageModel've created this entity classes, do not forget one more thing to do: "Object passed in AIDL, it is necessary in the class file under the same path, created with the same name, but the suffix .aidl file and use parcelable keyword to declare the class "in the file. code show as below:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

For no contact aidl students, the light that can make people ignorant force, take a look at this time of the project structure to steady your nerves:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

We have just added three files:

  • MessageSender.aidl -> defines the method for sending messages, automatically generates Binder class called MessageSender.Stub achieve in the service side, returned to the client calls
  • MessageModel.java -> Message Entity type, transmitted from the client to the server, implements serialization Parcelable
  • MessageModel.aidl -> declares MessageModel AIDL may be transferred, the packet on the same path with MessageModel.java

OK, I believe at this time ignorant force has been lifted -

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

2.5 created on the server MessageSender.aidl this AIDL interfaces automatically generated Binder object and returns to the client calls the server MessageService code is as follows:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

MessageSender.Stub Android Studio is based on the object of our MessageSender.aidl Binder file is automatically generated (As for how to generate, there will be an answer below), we need to put this Binder object is returned to the client.

2.6 client calls a remote method to get after the end of the Binder object

Call as follows:

  1. In onServiceConnected method of the client, to get the Binder object returned from the server;
  2. MessageSender.Stub.asInterface method used to obtain the corresponding user interface MessageSender.aidl;
  3. After obtaining MessageSender objects, like a common interface, like call the methods.

Then the client code is as follows:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

In the client sendMessage method we call MessageSender transmits a message to the server, and the generated MessageModel object as a parameter to the server, the print server the final result is as follows:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

There are two things to say:

  1. The server has received a message sent by the client, and printed correctly;
  2. Service and client distinguish between the two processes, PID is not the same, the process name is not the same;

Here, we have completed the basic use AIDL cross-process method call, but also the entire refinement process Step.0, you can then look at Step.0, since it has been to learn to use, the next ... the whole end of the play. . .

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

If I write to you the whole end of the play, then what's the difference with salted fish ...

Know, know why

We call flow above to see from the client to the server, have experienced some things to see how the upper Binder is working, as the underlying Binder, this is a very complex topic, this article does not get to the bottom. (See here if you would like to ask what is Binder, then taken to manually pour point of view ...)

Let's take a look at the calling process initiated from the client:

  1. MessageSender messageSender = MessageSender.Stub.asInterface(service);
  2. messageSender.sendMessage(messageModel);

Aside other independent code, the client inter-process adjustment method on these two steps, which are encapsulated in two steps MessageSender.java source MessageSender.aidl finally generated (specific path: the build directory in a subdirectory, found himself , unhappy you to hit me ah)

See below the code and comments, in front of high-energy warning ...

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Just look at the code, it may be a bit ignorant force, believe the combination of the code flow chart will look better understood below:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Starting sendMessage client calls the whole process AIDL shown above, asInterface method will be determined whether the method returns onBind Binder stored in the same process in the same process, the conventional method call, if in different processes, the entire data transfer process is required to be grouped by the underlying Binder (serialization, transmission, reception and deserialization), a method of obtaining the final data and then subjected to conventional calls.

Knock on the blackboard: cross-process nature of the object is serialized transmission, transmit, receive and deserialize such a process, which is why the process of transfer across the object must implement the interface Parcelable

Cross-process callback interface

  • In the above we have achieved the ability to send messages from the client to the server inter-process, then we also need to terminate the service of the remote server to receive the message, delivered to the client. Some students estimate will say: "This is not what the interface is a callback Well," set a callback interfaces thinking is correct, but here the use of callback interfaces bit different, passed in AIDL interfaces, can not be a common interface, only AIDL interface, so we need to create a AIDL interface to spread the service side, as a callback interface.

AIDL Interface MessageReceiver.aidl New Message received:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Next we register the callback interface to the server to modify our MessageSender.aidl:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

These are our ultimate good aidl modify the interface, then we need to make corresponding changes:

  1. Increase registration and the registration methods of the interface MessageSender in the service ends;
  2. MessageReceiver implement the interface in the client and server to register through MessageSender.

Client to change, modify MainActivity:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Client There are three changes:

  1. Increased messageReceiver target for server-side message listener notification;
  2. onServiceConnected method, the messageReceiver registered to go to the Service;
  3. onDestroy time of deregistration messageReceiver.

The following changes to the server MessageServie:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Server main changes:

  1. MessageSender.Stub realized the registration and anti-registration method callback interface;
  2. AIDL increased RemoteCallbackList to manage remote interface;
  3. FakeTCPTask simulate a long connection to inform the client a new message arrives. (Long connection here may be XMPP, Mina, Mars, Netty and so on, where to get hold of false meaning of meaning, there is time we open a post to talk XMPP)
  • There is also a need to talk about, is RemoteCallbackList, why should RemoteCallbackList, ordinary ArrayList not do it? Of course not, otherwise why has a whole RemoteCallbackList, registerReceiveListener and unregisterReceiveListener in client transport objects over, Binder after treatment, when the server receives is actually a new object, which results in unregisterReceiveListener when ordinary ArrayList is unable to find Add to that object List of the registerReceiveListener time, but Binder object of their underlying use is the same one, RemoteCallbackList use this feature did find the same object, so that we can successfully counter-interfaces registered clients to pass over the objects.

  • RemoteCallbackList After the client process terminates, it can automatically remove the listener client is registered, it also implements internal thread synchronization, so we do not need to consider thread synchronization, it is indeed a class of 666 in registration and the registration. (As for the use of unitary moths phenomenon ArrayList, you can see for yourself, space issues, there is not demonstrated)

This, the server notifies the client-related code is also finished, the results will not print correctly nothing more than a map, you can look at yourself Run, when the print attention to choose different processes, or stare at the screen too bad no log.

DeathRecipient

Do you think this would be finished? too young too simple ...
Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

I do not know you ever feel that the two processes interact always felt the lack of a sense of security ... so that the server processes such as Crash, while the client process wants to invoke server-side methods, so that the call can not. At this point we can set up a DeathRecipient subject to Binder, Binder meaning when the plug when we receive notification callback method DeathRecipient of the interface, and make the appropriate action, such as reconnection services.

DeathRecipient used as follows:

  1. Statement DeathRecipient target to achieve its binderDied method, when the binder death, will binderDied callback method;
  2. Binder object to set DeathRecipient object.

Client MainActivity statement DeathRecipient:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Binder in two important ways:

  1. linkToDeath -> Settings death proxy DeathRecipient objects;
  2. unlinkToDeath -> Binder case of death, the lifting of the agent.

In addition, Binder of Binder isBinderAlive can also determine whether death

Permission Validation

Even the bus, the car does not have to tick on the card, if you want our service process does not think the same on the bus who wants it on, then we can add permissions verification.

Describes two authentication methods:

  1. Check the custom permission in onBind server, if passed our check, a normal return Binder object, not by returning null check, the client returns null in the case of not bind to our services;
  2. In onTransact method of checking customer service side of the end of the package name, not by check directly return false, check by performing a normal process.

Custom permission, permission to increase the custom in Androidmanifest.xml in:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Check the permissions of the server method:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Depending on the process, do different initialization

I believe a couple of years ago many of my friends are still using Android-Universal-Image-Loader to load the picture, it is necessary to initialize the Application class. Make a example, we use it to load the picture, but also a picture selection process, we hope to allocate more cache to the picture selection process, or is it some other initialization, the picture does not need to choose how to do initialization process ?

Here to provide a simple and crude way, the blogger is so dry ... it directly to determine the process name, make the appropriate action to:

Spent two years, over ten thousand words best sum up your Android teach multi-process, micro-channel micro-Bo are using

Each process is created, the onCreate method is invoked Application, this is a place that needs attention, we can pid of the current process, to get the name of the current process of judgment to do, then we need to do some logic, our example two processes to get the name are:

  1. The client process: com.example.aidl
  2. Server process : com.example.aidl: remote

to sum up

  1. Multi-process app can apply multiple memory in the system, but should be reasonable, it is recommended to put some high-consumption, but not commonly used modules into separate processes, the process can not be used in time to manually shut down;
  2. Way to achieve a variety of multi-process: the four component is passed Bundle, Messenger, AIDL, etc., to choose their own usage scenarios;
  3. In the Android multi-process communication, it is recommended to use the system provided by Binder class that has achieved the multi-process communication without the need for us to do the underlying work;
  4. Multi-process applications, Application will be created multiple times;

Epilogue

This article written off for a long time, and I believe that the students could really use much, I choose such a topic is a thankless task ... but I still hope to provide a complete solution for everyone here. Simple to use multi-process, and results are obvious, such as the picture selection and WebView configuration to a separate process, which I hope we can take action. Knowledge point of this article is very large, it may not be too easy to understand, if you are interested, I suggest you to manually write it, then places do not understand, break point to see what kind of operation steps.

For the interview the students, when it comes to multi-process during the interview, with the interviewer chat open, is estimated to be able to add points, or in practical work, some use multiple processes can better solve the problem areas, you can During the meeting Paizhuo fierce play, with the director, said: "I have a bold idea ...", so install X is also good (of course, not fired, then none of my things ...)

The article is not easy, if you liked this article, or to help you hope a lot of attention Oh thumbs forward. Articles will be continuously updated. Absolutely dry! ! !

Guess you like

Origin blog.51cto.com/14775360/2484407