当前位置:网站首页>Bottom compulsory of large factory: "communication realization between application program and AMS"
Bottom compulsory of large factory: "communication realization between application program and AMS"
2022-07-23 07:52:00 【Android daily talk】
1、 Preface
We are in many and Framework Analyze relevant articles , Will see ActivityManagerService This class , But in the upper application development , But not many will directly use him
So why should we learn it , One of the most direct benefits is that it is the basis for us to understand the application startup process , Only with ActivityManagerService And the relationship of its related classes are well understood , We can sort out the process of application startup .app
Today's article , Let's do it right ActivityManagerService Make a simple summary of the communication mode with the application process , Here we are based on the communication direction between processes , It is divided into two parts to discuss :
From application process to manager process ide
(a) IActivityManager(b) ActivityManagerNative ActivityManagerProxy(d) ActivityManagerService function
From manager process to application process learning
(a) IApplicationThread(b) ApplicationThreadNative ApplicationThreadProxy(d) ApplicationThreadui
2、 From application process to manager process
Communication in this direction , The application process acts as the client , The manager process is the server . Let's take the simplest example , When we start a Activity, It is necessary to inform the overall manager , Let it be responsible for starting , The overall manager is running in another process , This involves the communication from the application process to the manager process
The classes involved in the communication process in this direction include :
2.1 The application process sends messages to the manager process
When we want to start a Activity, Will first call to Activity Of : agent
@Override
public void startActivityForResult(
String who, Intent intent, int requestCode, @Nullable Bundle options) {
//...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
intent, requestCode, options);
//...
}
Call... Later Instrumentation Of :
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
//....
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
//...
}
Here we see the top UML In the figure ActivityManagerNative, its getDefault() Method returns a IActivityManager Implementation class of :
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
//1. Get a proxy object
IBinder b = ServiceManager.getService("activity");
//2. Encapsulate the proxy object through another layer
IActivityManager am = asInterface(b);
return am;
}
};
static public IActivityManager getDefault() {
return gDefault.get();
}
here , about gDefault Variables have two descriptions :
- This is a
staticVariable of type , So call anywhere in the programgetDefault()Method accesses the same object in memory - Here we use
SingletonPattern , That is, a single example of lazy mode , Only the first callget()When the method is used , Will pass bycreate()Method to create an object
create() Did two things :
- after
ServieManagergetIBinder, ThisIBinderIt is the proxy object of the management process in the application process , afterIBinderOftransactMethod , We can send messages to the management process :
public boolean transact(int code, Parcel data, Parcel reply, int flags)
- take
IBinderPass inasInterface(IBinder b)Construct aIActivityManagerImplementation class of , Be able to see , What's coming back here is aActivityManagerProxyobject :
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// This step ignores ....
IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
below , Let's take a look at this ActivityManagerProxy, It has achieved IActivityManager Interface , We can see what it achieves IActivityManager Interface methods are passed in when constructing this object IBinder.transact(xxxx) To invoke the , The difference between these methods lies in the type of message and parameters .
class ActivityManagerProxy implements IActivityManager {
public ActivityManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
// This is also important , Let's analyze later ..
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
// Send a message to the manager process ...
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
}
Through the above analysis , Let's sum up in one sentence :
The application process goes through
ActivityManagerProxyInsideIBinder.transact(...)Send a message to the manager process , ThisIBinderIt is a proxy object of the manager process in the application process , It's throughServieManagerGot .
2.2 The manager process processes messages
below , Let's take a look at the processing of messages by the manager process , In the manager process , Finally, it goes through ActivityManagerService Manage various applications .
It inherited ActivityManagerNative class , Rewrite the Binder Class onTransact(...) Method , Let's pass by ActivityManagerProxy Of IBinder The message sent by the object will eventually be called to this function in the manager process ,ActivityManagerNative This method is rewritten :
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
String callingPackage = data.readString();
Intent intent = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
IBinder resultTo = data.readStrongBinder();
String resultWho = data.readString();
int requestCode = data.readInt();
int startFlags = data.readInt();
ProfilerInfo profilerInfo = data.readInt() != 0
? ProfilerInfo.CREATOR.createFromParcel(data) : null;
Bundle options = data.readInt() != 0
? Bundle.CREATOR.createFromParcel(data) : null;
// Here, processing operations are performed in the manager process ....
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
//...
}
stay onTransact(xxx) In the method , According to the type of message received , call IActivityManager Different interfaces defined in the interface , and ActivityManagerNative These interfaces are not implemented , The real deal is ActivityManagerService in ,ActivityManagerService Start a series of complex operations , Here, we will analyze it in detail later when we introduce the application startup process .
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
Same , Let's also summarize in one sentence :
The manager process goes through
onTransact(xxxx)Handle messages sent by applications
3、 From manager process to application process
next , Let's consider another way of communication , From manager process to application process , The communication process in this direction involves the following classes :
ApplicationThread The whole framework of is very similar to the above , Just in this direction , The manager process acts as the client , The application is the server .
3.1 The manager process sends messages to the application process
When we analyzed earlier , When the application process sends messages to the manager process , Is a IBinder This manager process is implemented by proxy objects in the application process , And this IBinder Is after ServiceManager Acquired :
IBinder b = ServiceManager.getService("activity");
Empathy , If the manager process wants to send messages to the application process , Then it must also try to get a proxy object of the application process on its side .
Let's recall , In the analysis of the second section , While the application process sends messages to the manager process , after writeStringBinder, Put the following object :
public int startActivity(IApplicationThread caller, ...) {
//...
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
//...
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
}
This caller Is called at the beginning startActivityForResult When it came in :
ActivityThread mMainThread;
@Override
public void startActivityForResult(
String who, Intent intent, int requestCode, @Nullable Bundle options) {
//...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
intent, requestCode, options);
//...
}
After check ActivityThread Code for , We can see that it is actually a definition in ApplicationThread Medium ApplicationThread object , its asBinder The realization is in ApplicationThreadNative among :
public IBinder asBinder() {
return this;
}
When the manager process receives messages , Can pass readStrongBinder Get this ApplicationThread Object is the proxy object of the manager process IBinder:
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
// Fetch incoming ApplicationThread object , Later call asInterface Method ..
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
//...
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
return true;
}
}
next , It passes again asInterface(IBinder xx) Method passes the passed in proxy object through ApplicationThreadProxy A layer of encapsulation :
static public IApplicationThread asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IApplicationThread in = (IApplicationThread) obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ApplicationThreadProxy(obj);
}
in the future , The manager process can pass through the proxy object transact(xxxx) Method sends a message to the application process :
class ApplicationThreadProxy implements IApplicationThread {
private final IBinder mRemote;
public ApplicationThreadProxy(IBinder remote) {
mRemote = remote;
}
public final IBinder asBinder() {
return mRemote;
}
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
//....
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
//...
}
This process can be summarized as :
The manager process goes through
ApplicationThreadProxyInsideIBinderSend a message to the application process , ThisIBinderIt is the proxy object of the application process in the manager process , It is obtained when the manager process receives the message sent by the application process .
3.2 User processes receive messages
In the user program process ,ApplicationThread Of onTransact(....) You can receive the message sent by the manager process , Call... Later ApplicationThread Achieved IApplicationThread Interface method for message processing :
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
data.enforceInterface(IApplicationThread.descriptor);
IBinder b = data.readStrongBinder();
boolean finished = data.readInt() != 0;
boolean userLeaving = data.readInt() != 0;
int configChanges = data.readInt();
boolean dontReport = data.readInt() != 0;
schedulePauseActivity(b, finished, userLeaving, configChanges, dontReport);
return true;
}
4、 Conclusion
The above is the communication mode between the application process and the manager process , The essence , Are obtained through the proxy object of the other process transact(xxxx) Method send message , And the other party's progress is onTransact(xxxx) Method to process messages , Thus, the communication between processes is realized
There is a need to learn more Android Advanced technology students ; I recommend myself 《 complete Android Information , And some video lectures 》 Now send a private message “ Advanced ” or “ note ” Free access to


Finally, I want to say :
For programmers , What to learn 、 There's too much technology , If you want not to be eliminated by the environment, you have to constantly improve yourself , It's always us to adapt to the environment , Not the environment to adapt us
Technology is endless , You need to do this for every line of code you submit 、 Each tool used is responsible for , Keep digging into its underlying principles , In order to sublimate their technology to a higher level
Android There is still a long way to go for an architect , Let me share with you
边栏推荐
猜你喜欢

11.37万的星瑞是怎样一个产品和表现力?一起来看看吧

Wechat campus second-hand book trading applet graduation design finished product (5) assignment

记一次线上SQL死锁事故:如何避免死锁?

93. (leaflet chapter) leaflet situation plotting - modification of attack direction

NB-IOT的四大特性

ASP.Net Core创建MVC项目上传多个文件(流方式)

Scala generic generic class details - t

Wechat campus second-hand book trading applet graduation design finished product (7) Interim inspection report

Implementation of remove function

ETL tool (data synchronization)
随机推荐
Wechat campus second-hand book trading applet graduation design finished product (1) development outline
Interpretation of URL structure
ROS2常用命令行工具整理ROS2CLI
etcdv3·watch操作实现及相关重点说明
Application of workflow engine in vivo marketing automation
NB-IOT的四大特性
Graduation project ----- Internet of things environment detection system based on stm32
局域网SDN技术硬核内幕 9 从软件Overlay到硬件Overlay
Scala learning -- six uses of generics [t]
聊聊并发编程的12种业务场景
Mysql的索引为什么用B+树而不是跳表?
Overview of multisensor fusion -- FOV and bev
scala 主构造器_Scala主构造器深度
模拟Not All Endpoints Registered异常及解决方案
【开发技术】SpingBoot数据库与持久化技术,JPA,MongoDB,Redis
4G传输模块的功能应用
Classes and objects (1)
Wechat campus second-hand book trading applet graduation design finished product (4) opening report
ROS based navigation framework
BGP笔记(二)