1 Required knowledge points
1.1 Processes and threads
To understand the inter-process communication, you first need to understand the following knowledge points 1 :
- Process : According to the description of the operating system, the process is the smallest unit of resource allocation, a process can contain multiple threads
- Threads : Threads are the smallest unit of CPU scheduling. Multithreading needs to consider concurrency issues.
1.2 Multi-process in Android
Android multi-process refers to the situation where there are multiple processes in an application. In Android, there is generally one process for an application. Multi-process case 2 :
- An application needs to be implemented in multi-process mode due to its own reasons
- In order to increase the memory available for an application, multiple processes are used to obtain multiple copies of memory space
Turn on multi-process mode by AndroidManifest
specifying Android:process
attributes in
<activity
android:name=".SecondActivity"
android:process=":twoprocess"></activity>
<activity
android:name=".ThirdActivity"
android:process="com.yds.thirdprocess"></activity>
- To
“:”
process the beginning of the application process is privately owned, the other components of the application can not run with it in the same process, rather than to the beginning of the colon global process data, applications by othershareUID
ways and it can be run in the same process. shareUID
: The Android system will allocate a different level of UID to each program. If you need to call each other, only the same UID is required. This makes the shared data have a certain degree of security. Each software cannot obtain data at will. Yes, and the same Application has only one UID, so there is no problem of access rights between Applications.
Generally speaking, the use of multiple processes will have the following problems:
- Static members and singleton mode completely fail
- The thread synchronization mechanism is completely invalid
- SP (SharedPreference) reliability will decline
- Application created multiple times
1.3 Data sharing methods
If you need to make a Application
share of some services Service
, Provider
or Activity
other data, there are three ways:
- Full exposure: use
android:exported="true"
, once settrue
, it will be fully exposed, and the exposed data can be called by other application processes. No useandroid:exported
ofService
,Provider
orActivity
, its defaultexported
valuefalse
, but if this time is setintent filter
, the default value is true. - Permission prompt exposed: If application A is set
android:permission="xxx.xxx.xxx"
, you must useuse-permission
it in the manifest to access the things of application A. - Private exposure: If a company has made two products and only wants to call each other between these two products, then this time you must use
shareUserID
to force the Uid of both software to be the same. In this case, you must use a signed document with the company's signature. If you use a system's own softwareShareUID
, such as Contact, no third-party signature is required. 3
1.4 Introduction to IPC basic concepts
Serialiazable
With Parcelable
:
- Serialization: The process of converting objects into bytes
Serialiazable
: Serialization interface provided by JavaParcelable
: Serialization interface provided by Android
Serialiazable
And Parcelable
the difference between : Serialiazable
simple but requires a lot of I / O operations, Parcelable
the use of relatively complex, mainly for the sequence of memory, high efficiency.
Binder
:
See [IPC] Binder cross-process communication mechanism for details
2 Realization of IPC
There are several ways to achieve IPC 4 :
- use
Bundle
- Use file sharing
- use
SharedPreferences
- use
Messenger
- use
AIDL
- use
ContentProvider
- Use
Binder
connection pool - Broadcast
- Socket
- pipeline
2.1 Using Messenger
Messenger
Known as the messenger, it is often Message
used together with cross-process communication. The bottom layer is just the right Binder
simple packaging
- step
- Create a
Service
, inService
theonBind
return in aIBinder
subject. - In
AndroidManifest
the statement the service, and the service on another one process - By
bindService
binding service - Create an
ServiceConnection
object on the client , use theIBinder
object returned by the server to create oneMessenger
, whichMessenger
is the serverMessenger
, you canMessenger
send the client data to the server (this method is to pass data from the client to the server, if you want to send data from the server To transfer data from the client, you can create anHandler
object on the client , then create a client from the objectMessenger
, then send the client to the server throughmessage.replyTo
5Messenger
, then get the client's creation on the serverMessenger
, and then send the data through Messenger To the client, so that the server transmits data to the client) - By
mMessenger.send(message)
sending data to the server, cross-process communication is achieved.
- Code for
creating aService
, inService
theonBind
return in aIBinder
subject.
/**
* Created by yds
* on 2020/4/13.
*/
public class MessengerService extends Service {
//服务端自己的信使,为了获取客户端数据
private Messenger mMessenger;
//客户端信使对象,为了将数据发送到客户端
private Messenger cMessenger;
@Override
public IBinder onBind(Intent intent) {
mMessenger = new Messenger(new MyHandler());
System.out.println("MessengerService onBind");
return mMessenger.getBinder();
}
class MyHandler extends Handler{
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 0:
Message message = Message.obtain(null,1);
message.arg1 = 1000;
//获取客户端传递来的信使
cMessenger = msg.replyTo;
try {
//通过客户端信使发送服务端数据到客户端
cMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
System.out.println("MessengerService handleMessage");
break;
}
}
}
}
In AndroidManifest
the statement the service, and the service on another one process
<service android:name=".MessengerService"
android:process="com.yds.test.messengerservice"/>
Use Messenger to realize two-way communication between client and server
public class MainActivity extends AppCompatActivity {
//服务端信使,为了发送数据到客户端
private Messenger mMessenger;
//客户端自己的信使,为了获取服务端数据
private Messenger cMessenger;
private static class MyHandler extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
System.out.println("Service Data: " + msg.arg1);
break;
}
}
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMessenger = new Messenger(service);
cMessenger = new Messenger(new MyHandler());
if (mMessenger != null) {
Message msg = Message.obtain(null, 0);
//将客户端自己的信使放在Message里传递到服务端
msg.replyTo = cMessenger;
try {
mMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mMessenger = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
}
}
Run screenshot:
2.2 Using Bundle
Bundle
It is a final
type and cannot be inherited. It implements the Parcelable interface and is a special Map type that supports interprocess communication.
Using Bundle for inter-process communication is actually achieved through Messenger + Message. The core code is as follows:
mMessenger = new Messenger(service);
Message msg = Message.obtain(null, 0);
Bundle bundle = new Bundle();
bundle.putString("IPC", "Bundle");
bundle.putInt("Number", 20);
msg.setData(bundle);
try {
mMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
2.3 使用SharedPreferences
SharedPreferences
It is not suitable for storing large amounts of data and frequently changing data. It can only be used for lightweight storage. Data may be lost during high concurrent read / write. SharedPreferences
There are the following performance issues 6 :
- Cross-process is not safe . Since cross-process locks are not used, even if they are used
MODE_MULTI_PROCESS
,SharedPreferences
frequent reads and writes in cross-processes may cause all data to be lost. According to online statistics,SharedPreferences
there will be about 1 in 10,000 damage rates. - Loads slowly .
SharedPreferences
The file loading uses asynchronous threads, and the loading thread has not set a priority. If you read data at this time, you need to wait for the end of the file loading thread. This leads to the main thread waits for low-priority thread lock problems, such as a100KB
theSP
file read latency, approximately50 ~ 100ms
, and suggest that you start early with pre-loading process used in theSP
file. - Write in full . Either
commit()
or notapply()
, even if we only change one of the entries, the entire content will be written to the file. And even if we write the same file multiple times, weSP
have not merged multiple changes into one, which is one of the important reasons for poor performance. - Caton . As a
apply
mechanism of asynchronous disk placement (copy to disk) is provided , data may be lost in the event of a crash or other abnormal conditions. So when the application receives a broadcast system, or by callingonPause
some other occasion, the system will force all theSharedPreferences
landing data objects to disk. If it is not completed, the main thread will be blocked all the time. This is very likely to cause Caton, evenANR
, from online data,SP
Caton accounting generally exceed5%
.
For the above reasons, it is not recommended to use SharedPreferences
cross-process communication, especially SharedPreferences
cross-process communication is not secure.
2.4 Using file sharing
Use multiple processes to read and write the same external file at the same time to achieve the purpose of data interaction, the storage form is not limited: xml, text, object serialization and so on. But it has obvious shortcomings. Since the Linux system has no restrictions on concurrent reading and writing of files, it will cause data out-of-synchronization, so this method is only suitable for inter-process communication with low data synchronization requirements.
2.5 Using AIDL
In order for other applications to access the services provided by this application, the Android system uses remote procedure call (Remote Procedure Call,RPC)
. Like many other RPC-based solutions, Android uses an interface definition language (Interface Definition Language,IDL)
to expose service interfaces. Many IPC communication methods are based AIDL
. Such as Service
, ContentProvider
etc.
AIDL
The simple use is visible: AIDL simple use