Android interview questions: bindService obtain the proxy is synchronous or asynchronous?

Android in bindService is an asynchronous process, what does that mean? Use bindService simply want to get a Binder Proxy service, but this is not the time to get proxy initiator controlled by bindService, but is controlled by the Service end, that is to say after bindService, APP will not get Proxy end immediately, while Service is to wait for notification APP end, the specific process can be simplified as follows:

  • APP bindService to end the first AMS through registration, to explain their need to bind such a service, and leave the delivery address
  • APP to come back and continue to do other things, it can be seen as non-blocking
  • AMS start the service end notification Service
  • Service starts and notify AMS Booted
  • AMS catch before leaving the end of address notification APP APP end and passed to the Proxy proxy APP end

Look more directly through the code

 void test(){
 bindService(intent, new ServiceConnection() {
 @Override
 public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
 iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);
 Log.v(TAG, "onServiceConnected..." );
 }
 @Override
 public void onServiceDisconnected(ComponentName componentName) {
 }
 }, Context.BIND_AUTO_CREATE);
 Log.v(TAG, "end..." );
 }

</>

BindService in the process, Log code above should be kind of how it? If bindService is a synchronous process, then the Log should be as follows:

TAG onServiceConnected ...
TAG end ...

But because it is an asynchronous process, the following real Log

TAG end ... 
TAG onServiceConnected ...

That bindService APP does not block waiting for clients to obtain Proxy, but directly returned, which can be supported from the source code, skip directly to see ActivityManagerNative

public int bindService(IApplicationThread caller, IBinder token,
 Intent service, String resolvedType, IServiceConnection connection,
 int flags, int userId) throws RemoteException {
 Parcel data = Parcel.obtain();
 Parcel reply = Parcel.obtain();
 data.writeInterfaceToken(IActivityManager.descriptor);
 data.writeStrongBinder(caller != null ? caller.asBinder() : null);
 data.writeStrongBinder(token);
 service.writeToParcel(data, 0);
 data.writeString(resolvedType);
 data.writeStrongBinder(connection.asBinder());
 data.writeInt(flags);
 data.writeInt(userId);

 mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
 reply.readException();
 int res = reply.readInt();
 data.recycle();
 reply.recycle();
 return res;
}

mRemote.transact (BIND_SERVICE_TRANSACTION, data, reply, 0) really does make APP end the calling thread blocks, waiting for the implementation of AMS BIND_SERVICE_TRANSACTION request, but AMS is not awakened Service before returning in the implementation of this request, it returns an earlier time, and then look ActivityManagerService,

public int bindService(IApplicationThread caller, IBinder token,
 Intent service, String resolvedType,
 IServiceConnection connection, int flags, int userId) {
 ...
 synchronized(this) {
 return mServices.bindServiceLocked(caller, token, service, resolvedType,
 connection, flags, userId);
 }
}

ActivityManagerService direct call function bindServiceLocked ActiveServices, the request binding Service, APP-side thread here is still blocked waiting for AMS server returns, assuming that the process has started but in which the Service Service does not start, then ActiveServices further calls bindServiceLocked-> realStartServiceLocked to start Service, interesting here:

 private final void realStartServiceLocked(ServiceRecord r,
 Proce***ecord app) throws RemoteException {
 ...

 app.thread.scheduleCreateService(r, r.serviceInfo,
 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
 ...

 requestServiceBindingsLocked(r);

app.thread.scheduleCreateService Binder is a communication process, he is actually AMS asynchronous request ActivityThread in ApplicationThread services, system service requests client's local services are generally asynchronous:

// 插入消息,等待主线程执行
public final void scheduleCreateService(IBinder token,
 ServiceInfo info, CompatibilityInfo compatInfo) {
 CreateServiceData s = new CreateServiceData();
 s.token = token;
 s.info = info;
 s.compatInfo = compatInfo;

 queueOrSendMessage(H.CREATE_SERVICE, s);
}

However, this request is directly inserted into the thread Service ActivityThread end of a message directly on the return, but did not wait until the request is executed because AMS used very frequently, never old waiting for the client to complete some tasks, so AMS end to the client sending the command directly returns, this time in fact Service has not been created, that is, the request is only half completed, onServiceConnected also does not perform, onServiceConnected when to enforce it? app.thread.scheduleCreateService APP end is inserted into the first message, is used to create the Service, requestServiceBindingsLocked in fact, the second message, to handle bound

private final boolean requestServiceBindingLocked(ServiceRecord r,
 IntentBindRecord i, boolean rebind) {
 ...

 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);

The second message is to deal with some binding requirements, Android's Hanlder message handling mechanism ensures that the second message must be performed after the first message,

public final void scheduleBindService(IBinder token, Intent intent,
 boolean rebind) {
 BindServiceData s = new BindServiceData();
 s.token = token;
 s.intent = intent;
 s.rebind = rebind;
 queueOrSendMessage(H.BIND_SERVICE, s);
}

After more than two messages inserted, AMS end wakes up, and then re-awaken bindService end blocked before, but this time, Service does not have to be created, so it was unknown asynchronous process, Service-side processing of the first message It creates Service,

private void handleCreateService(CreateServiceData data) {
 ...
 LoadedApk packageInfo = getPackageInfoNoCheck(
 data.info.applicationInfo, data.compatInfo);
 Service service = null;
 try {
 java.lang.ClassLoader cl = packageInfo.getClassLoader();
 service = (Service) cl.loadClass(data.info.name).newInstance();
 ...

When the implementation of the second message, it will request publishService to AMS, in fact, tell the AMS, the services are started, you can request to APP before the end of the distribution agent.

private void handleBindService(BindServiceData data) {
 Service s = mServices.get(data.token);
 if (s != null) {
 try {
 data.intent.setExtrasClassLoader(s.getClassLoader());
 try {
 if (!data.rebind) {
 IBinder binder = s.onBind(data.intent);
 ActivityManagerNative.getDefault().publishService(
 data.token, data.intent, binder);
 ... 

After the client receives publishService AMS message, a notification will be sent to the end of APP, APP and thus end the callback function onServiceConnected by Binder, while passing Proxy Binder Service Agent

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
 ...
 try {

 c.conn.connected(r.name, service);
 } catch (Exception e) {}

Here, onServiceConnected will be called back, however, as to when to end it two messages Service executed, there is no guarantee, perhaps due to special reasons, and that two messages will never be executed, it will not be called back onServiceConnected, but this will not affect the AMS and other issues APP end, because if these messages are not blocked two of them have been executed, and simple process is as follows:

Android interview questions: bindService obtain the proxy is synchronous or asynchronous?

bindService asynchronous process

Finally, the fact startService is asynchronous.


Thank you for patience and ability, La miles long-winded reading my article.

We are willing to stick with you in Android development positions of fellow mutual exchange of learning and common progress!

Here I also share a copy of your collection of finishing Android studying architecture PDF + Video + Interview + document source notes , as well as advanced technical architecture Advanced Brain Mapping, Android interview with thematic development, advanced materials advanced architecture to help you enhance Advanced Learning , but also saves everyone time online in search of information to learn, you can also share with close friends studying together

If you have a need, you can point praise , concern me
Android interview questions: bindService obtain the proxy is synchronous or asynchronous?

Guess you like

Origin blog.51cto.com/14573572/2446922