注册

Android知识点之Service(二)

(2)、绑定服务流程(同进程)

a、应用内调用到AMS过程

在Activity环境下调用bindService方法
frameworks/base/core/java/android/content/ContextWrapper.java


public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
//mBase就是Activity在启动时在ActivityThread中创建的ContextImpl.java对象
return mBase.bindService(service, conn, flags);
}
复制代码

frameworks/base/core/java/android/app/ContextImpl.java


public boolean bindService(Intent service, ServiceConnection conn, int flags) {
····
return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
getUser());
}

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
String instanceName, Handler handler, Executor executor, UserHandle user) {
IServiceConnection sd;
····
//创建一个IServiceConnection的binder实现对象,内部封装ServiceConnection对象
//该对象传输到AMS所在进程中,AMS通过IServiceConnection的binder实现对象可以调用应用中IServiceConnection实现方法
if (mPackageInfo != null) {
//当在绑定服务调用bindService方法有传入Executor对象,则executor不为null
if (executor != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
} else {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
}
····
try {
····
//通过Binder机制跨进程调用AMS的bindIsolatedService方法
//sd为IServiceConnection对象,是一个Binder实现类,通过封装ServiceConnection得到
//sd的作用也是跨进程通信,当通过bindIsolatedService方法进入AMS进程处理时,
//AMS通过需要绑定的服务的`public IBinder onBind(Intent intent)`方法获取到一个自定义的Binder对象实现类,
//通过sd的connected方法将这个自定义的Binder实现类回传到应用进程ServiceConnection类的onServiceConnected方法中
//这个自定义的Binder实现类可以跨进程通信,绑定的服务是不同进程的可以通过这个参数跨进程通信
int res = ActivityManager.getService().bindIsolatedService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
····
return res != 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
复制代码

IServiceConnection的binder实现对象创建过程
frameworks/base/core/java/android/app/LoadedApk.java


public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
return getServiceDispatcherCommon(c, context, handler, null, flags);
}

public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Executor executor, int flags) {
return getServiceDispatcherCommon(c, context, null, executor, flags);
}

private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
Context context, Handler handler, Executor executor, int flags) {
synchronized (mServices) {
·····
//当在绑定服务调用bindService方法有传入Executor对象,则executor不为null
if (executor != null) {
sd = new ServiceDispatcher(c, context, executor, flags);
} else {
sd = new ServiceDispatcher(c, context, handler, flags);
}
····
return sd.getIServiceConnection();
}
}

static final class ServiceDispatcher {

private final ServiceDispatcher.InnerConnection mIServiceConnection;

//创建出IServiceConnection对象
private static class InnerConnection extends IServiceConnection.Stub {
····
}

ServiceDispatcher(ServiceConnection conn,
Context context, Handler activityThread, int flags) {
mIServiceConnection = new InnerConnection(this);
····
}

ServiceDispatcher(ServiceConnection conn,
Context context, Executor activityExecutor, int flags) {
mIServiceConnection = new InnerConnection(this);
····
}

IServiceConnection getIServiceConnection() {
return mIServiceConnection;
}
}
复制代码

b、AMS处理以及调用ActivityThread过程

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java


public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String instanceName,
String callingPackage, int userId) throws TransactionTooLargeException {
····
synchronized(this) {
//mServices对应的是ActiveServices.java对象
//caller为ActivityThread中的ApplicationThread的Binder机制实现类,用于与应用进程通信
//connection为IServiceConnection的Binder机制实现类,用于与应用进程通信
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, instanceName, callingPackage, userId);
}
}
复制代码

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java


int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String instanceName, String callingPackage, final int userId)
throws TransactionTooLargeException {
····
//flags在绑定过程的时候传的是Context.BIND_AUTO_CREATE,即是1
if ((flags & Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
//启动服务
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null) {
return 0;
}
}
····
return 1;
}

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
····
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
····
ProcessRecord app;
//判断启动的服务进程是否存在
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
···
if (app != null && app.thread != null) {
try {
····
//存在则直接启动服务
realStartServiceLocked(r, app, execInFg);
return null;
}
···
}
} else {
//启动的服务进程不存在,需要创建HostingRecord辅助开启创建进程
if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
r.definingUid);
}
}
//启动的服务进程不存在,创建一个新的进程
if (app == null && !permissionsReviewRequired) {
//启动一个新进程
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) {
····
}
····
}
····
return null;
}

private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
····
//启动ANR弹窗任务,当启动前台服务超过20s或者后台服务超过200s时,会弹ANR系统窗口提示应用无响应
bumpServiceExecutingLocked(r, execInFg, "create");
····
try {
····
//跨进程调用应用ActivityThread对象,进而调用service的onCreate生命周期方法
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
····
created = true;
} catch (DeadObjectException e) {
····
} finally {
//启动出现异常,那么ANR弹窗任务需要移除掉
if (!created) {
····
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
····
}
}
···
//如果是绑定服务,那么需要把自定义的Binder对象通过IServiceConnection回传
requestServiceBindingsLocked(r, execInFg);
···
}
复制代码

绑定服务是有自定义的Binder对象,这个需要通过AMS回传到应用进程中,也就是回传到ActivityThread里,看到requestServiceBindingsLocked方法的操作
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java


private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
throws TransactionTooLargeException {
for (int i=r.bindings.size()-1; i>=0; i--) {
//只有是绑定服务当前IntentBindRecord对象才有具体绑定的设置值
IntentBindRecord ibr = r.bindings.valueAt(i);
if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
break;
}
}
}

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
····
//防止重复绑定判断
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
···
//调用应用进程ActivityThread中的ApplicatonThread的scheduleBindService方法,进行数据回传
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.getReportedProcState());
//防止重复绑定的限制
if (!rebind) {
i.requested = true;
}
····
} catch (TransactionTooLargeException e) {
····
//绑定出现异常,那么ANR弹窗任务需要移除掉
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
throw e;
} catch (RemoteException e) {
···
//绑定出现异常,那么ANR弹窗任务需要移除掉
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
return false;
}
}
return true;
}
复制代码

c、应用ActivityThread处理过程

service的onCreate生命周期方法流程
frameworks/base/core/java/android/app/ActivityThread.java


public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
//向主线程发送一条消息
sendMessage(H.CREATE_SERVICE, s);
}

class H extends Handler {
public void handleMessage(Message msg) {
····
switch (msg.what) {
····
case CREATE_SERVICE:
····
//主线程处理Server启动
handleCreateService((CreateServiceData) msg.obj);
····
break;
····
}
}
}

private void handleCreateService(CreateServiceData data) {
····
try {
····
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用Server生命周期方法
service.onCreate();
····
try {
//调用AMS的serviceDoneExecuting方法移除Server超时监测任务
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
····
}
}
复制代码

绑定service的onBind或者onRebind生命周期方法流程
frameworks/base/core/java/android/app/ActivityThread.java


public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
updateProcessState(processState, false);
BindServiceData s = new BindServiceData();
s.token = token;
s.intent = intent;
s.rebind = rebind;
....
//向主线程发送一条消息
sendMessage(H.BIND_SERVICE, s);
}

class H extends Handler {
public void handleMessage(Message msg) {
····
switch (msg.what) {
····
case BIND_SERVICE:
···
handleBindService((BindServiceData)msg.obj);
···
break;
····
}
}
}

private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
····
if (s != null) {
try {
····
try {
if (!data.rebind) {
//获取到服务自定义的Binder对象,也是调用onBind生命周期方法
IBinder binder = s.onBind(data.intent);
//调用AMS所在进程的publishService方法进一步处理
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
//重复绑定时执行的方法,代表已经绑定过
//调用onRebind生命周期方法
s.onRebind(data.intent);
//调用AMS所在进程的serviceDoneExecuting方法移除ANR任务
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
}
····
} catch (Exception e) {
····
}
}
}
复制代码

d、AMS继续处理绑定服务内的Binder实现类流程

此过程的目的是将绑定的服务内部onBind方法自定义的Binder实现对象回传到应用进程ServiceConnection类的onServiceConnected方法中
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java


public void publishService(IBinder token, Intent intent, IBinder service) {
····
synchronized(this) {
····
//service是绑定服务内部onBind方法自定义的Binder实现类
//token是ActiveServices中创建的Binder实现类
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
复制代码

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java


void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
···
try {
····
if (r != null) {
····
if (b != null && !b.received) {
····
for (int conni = connections.size() - 1; conni >= 0; conni--) {
ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
····
try {
//调用到应用层注册的IServiceConnection的binder实现对象
//IServiceConnection是在应用层的LoadedApk.java对象内部类ServiceDispatcher中的内部类InnerConnection实现的
//InnerConnection对象继承了IServiceConnection.Stub
c.conn.connected(r.name, service, false);
}
····
}
}
}
//移除ANR超时任务
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
}
····
}
复制代码

e、应用进程处理绑定服务内的Binder实现类流程

frameworks/base/core/java/android/app/LoadedApk.java


static final class ServiceDispatcher {
//跨进程通信Binder实现类
private static class InnerConnection extends IServiceConnection.Stub {

····

//AMS所在的进程调用此方法把绑定服务内部onBind中实现的Binder对象回调到ServiceConnection注册者
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
}

public void connected(ComponentName name, IBinder service, boolean dead) {
//如果在应用绑定服务在bindService方法中有传Executor对象这个参数,那么mActivityExecutor就不为null
if (mActivityExecutor != null) {
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
} else if (mActivityThread != null) {
///如果在应用绑定服务在bindService方法中没有传Executor对象这个参数,
// 那么会通过mMainThread.getHandler()获取到ActivityThread中的H对象,此时mActivityThread不为null
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
//基本不会调用到这里
doConnected(name, service, dead);
}
}

//定义一个
private final class RunConnection implements Runnable {
···
public void run() {
···
//调用此方法进一步处理
doConnected(mName, mService, mDead);
····
}
····
}

public void doConnected(ComponentName name, IBinder service, boolean dead) {
·····
//mConnection对应ServiceConnection对象,最终通过onServiceConnected将绑定服务的内部Binder对象返回给注册者
if (service != null) {
mConnection.onServiceConnected(name, service);
} else {
// The binding machinery worked, but the remote returned null from onBind().
mConnection.onNullBinding(name);
}
}
}
复制代码


作者:小狼人爱吃萝卜
链接:https://juejin.cn/post/7008699606372450341
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册