Android源码阅读,绑定Service源码分析
2018-04-03 本文已影响149人
Sky_Blue
一、怎么去分析绑定服务的流程
带着下面这些疑问去看源码
1.Service是怎么创建的?
2.Service是怎么绑定的?
3.Service的回调在哪里调用?
二、一般绑定一个创建好的远程服务(服务的创建我就不多说)
public void bind(View view) {
Intent service = new Intent();
service.setAction("com.wen.user.service");
service.setPackage("com.wen.routerdemo");
// 创建并绑定服务
bindService(service, conn, Context.BIND_AUTO_CREATE);
}
// 绑定解绑的回调类
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(TestActivity.this, "onServiceConnected", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(TestActivity.this, "onServiceDisconnected", Toast.LENGTH_SHORT).show();
}
};
三、bindService源码分析
@Override
public boolean bindService(Intent service, ServiceConnection conn,int flags) {
// mBase其实是ContextImpl
return mBase.bindService(service, conn, flags);
}
四、找到ContextImpl类的bindService方法
@Override
public boolean bindService(Intent service, ServiceConnection conn,int flags) {
// mMainThread是ActivityThread
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),Process.myUserHandle());
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user) {
IServiceConnection sd;
if (conn == null) {
// 回调空会抛异常
throw new IllegalArgumentException("connection is null");
}
if (mPackageInfo != null) {
// 创建ServiceDispatcher类和IServiceConnection的实现类
// ServiceDispatcher类是对ServiceConnection回调和IServiceConnection等一些参数的封装
// 这个类很关键,后面的回调就是在这里
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
try {
IBinder token = getActivityToken();
// ActivityManager.getService()通过Binder机制获取到ActivityManagerService
// 最终会调用ActivityManagerService的bindService方法
int res = ActivityManager.getService().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
return res != 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
五、找到ActivityManagerService的bindService方法
public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String callingPackage,
int userId) throws TransactionTooLargeException {
synchronized(this) {
// 这里又去调用ActiveServices类的bindServiceLocked方法
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, callingPackage, userId);
}
}
五、再去找ActiveServices类的bindServiceLocked方法
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String callingPackage, final int userId) throws TransactionTooLargeException {
// 对查找服务信息的封装
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
ServiceRecord s = res.record;
try {
// 传的flags标记
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
// 创建Service的重要方法,返回是空,所以继续往下走。
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null) {
return 0;
}
}
if (s.app != null && b.intent.received) {
if (b.intent.apps.size() == 1 && b.intent.doRebind) {
// 绑定Service的关键方法
requestServiceBindingLocked(s, b.intent, callerFg, true);
}
} else if (!b.intent.requested) {
// 绑定Service的关键方法
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
return 1;
}
// 创建Service的重要方法
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;
final String procName = r.processName;
String hostingType = "service";
ProcessRecord app;
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
// 锁定要开启的Service
realStartServiceLocked(r, app, execInFg);
// 这里返回null
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
}
} else {
app = r.isolatedProc;
}
return null;
}
// 锁定要开启的Service
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
try {
// 终于看到希望,调用ActivityThread去创建Service
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
mAm.appDiedLocked(app);
throw e;
} finally {
if (!created) {
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
// Cleanup.
if (newService) {
app.services.remove(r);
r.app = null;
}
// Retry.
if (!inDestroying) {
scheduleServiceRestartLocked(r, false);
}
}
}
}
// 绑定服务的关键方法
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
// 绑定服务
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
}
}
return true;
}
在这里终于看到,调用ActivityThread去创建Service的方法:app.thread.scheduleCreateService()和绑定Service的方法:r.app.thread.scheduleBindService()。
六、Service的创建
找到ActivityThread里面scheduleCreateService方法,这方法通过Handler发送个消息,然后来到handleCreateService方法。
private void handleCreateService(CreateServiceData data) {
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
// 通过反射创建Service
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
}
try {
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
// 调用Service的attach方法
service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService());
// 调用Service的onCreate()方法
service.onCreate();
// 添加到ArrayMap集合
mServices.put(data.token, service);
} catch (Exception e) {
}
}
七、Service的绑定
找到ActivityThread里面scheduleBindService方法,这方法通过Handler发送个消息,然后来到handleBindService方法。
private void handleBindService(BindServiceData data) {
// 从集合里面获取Service
Service s = mServices.get(data.token);
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
// 调用服务的onBind()方法,得到IBinder
IBinder binder = s.onBind(data.intent);
// 调用ActivityServiceManager的publishService方法
ActivityManager.getService().publishService(data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
} catch (RemoteException ex) {
}
} catch (Exception e) {
}
}
}
// 这里是ActivityServiceManager类里面的方法
public void publishService(IBinder token, Intent intent, IBinder service) {
synchronized(this) {
// 调用ActiveServices的publishServiceLocked
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
// ActiveServices的publishServiceLocked
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
try {
if (r != null) {
Intent.FilterComparison filter
= new Intent.FilterComparison(intent);
IntentBindRecord b = r.bindings.get(filter);
if (b != null && !b.received) {
b.binder = service;
b.requested = true;
b.received = true;
for (int conni=r.connections.size()-1; conni>=0; conni--) {
ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
ConnectionRecord c = clist.get(i);
try {
// 调用IServiceConnection的connected方法
// IServiceConnection在ContextImpl类bindServiceCommon方法里面创建
// 去ContextImpl类bindServiceCommon方法找到IServiceConnection的实现类ServiceDispatcher里面的mIServiceConnection
// 也就是InnerConnection-->>connected(ComponentName name, IBinder service, boolean dead)
c.conn.connected(r.name, service, false);
} catch (Exception e) {
}
}
}
}
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
//实现类ServiceDispatcher,这个类在LoadedApk类里面
static final class ServiceDispatcher {
private final ServiceDispatcher.InnerConnection mIServiceConnection;
private final ServiceConnection mConnection;
private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd) {
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}
// 1.先来到这里
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
// 2.调用ServiceDispatcher的connected方法
sd.connected(name, service, dead);
}
}
}
ServiceDispatcher(ServiceConnection conn,
Context context, Handler activityThread, int flags) {
mIServiceConnection = new InnerConnection(this);
mConnection = conn;
mContext = context;
mActivityThread = activityThread;
mLocation = new ServiceConnectionLeaked(null);
mLocation.fillInStackTrace();
mFlags = flags;
}
// 2.调用ServiceDispatcher执行connected方法
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
// 3. 调用doConnected方法
doConnected(name, service, dead);
}
}
public void doConnected(ComponentName name, IBinder service, boolean dead) {
// 删掉N行代码
synchronized (this) {
// If there is a new service, it is now connected.
if (service != null) {
// 执行ServiceConnection连接的回调
mConnection.onServiceConnected(name, service);
}
}
}
}
八、总结
1.Service的创建是在ActivityThread类的handleCreateService方法里通过反射进行创建的,创建后紧接着调用Service的attach()方法,然后调用onCreate()方法。
2.紧跟着Service的onBind(Intent intent)方法是在ActivityThread类的handleBindService方法里调用
3.最后绑定服务的客户端ServiceConnection 类的回调是在ServiceDispatcher这个类调用的 doConnected()方法回调。