Service绑定形式启动过程
Posted 流云易采
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Service绑定形式启动过程相关的知识,希望对你有一定的参考价值。
一、绑定形式Service的使用 1)定义一个Service,注意重写onBind方法,返回一个IBinder对象public class MyService extends Service
public static final String LOG_TAG = "LOG_TAG";
private MyBinder mBinder = new MyBinder();
public class MyBinder extends Binder
public MyService getService()
return MyService.this;
@Override
public void onCreate()
super.onCreate();
Log.d(LOG_TAG, "onCreate");
@Override
public int onStartCommand(Intent intent, int flags, int startId)
Log.d(LOG_TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId);
@Nullable
@Override
public IBinder onBind(Intent intent)
Log.d(LOG_TAG, "onBind");
return mBinder;
@Override
public boolean onUnbind(Intent intent)
Log.d(LOG_TAG, "onUnbind");
return super.onUnbind(intent);
@Override
public void onDestroy()
super.onDestroy();
Log.d(LOG_TAG, "onDestroy");
2)注意在manifest中注册service
<service android:name=".MyService"/>
3)在Activity中bindService:
public class ServiceActivity extends AppCompatActivity
private MyService mService;
// 定义ServiceConnection
private ServiceConnection conn = new ServiceConnection()
@Override
public void onServiceConnected(ComponentName name, IBinder service)
// 通过定义的Binder来获取Service实例来供使用
mService = ((MyService.MyBinder) service).getService();
Log.w(MyService.LOG_TAG, "Activity onServiceConnected");
@Override
public void onServiceDisconnected(ComponentName name)
mService = null;
// 当Service被意外销毁时
Log.w(MyService.LOG_TAG, "Activity onServiceDisconnected");
;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.empty_ayout);
@Override
protected void onResume()
super.onResume();
// bindService
Intent intent = new Intent(this, MyService.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
Log.w(MyService.LOG_TAG, "Activity bindService");
@Override
protected void onPause()
super.onPause();
// 进行unbind
unbindService(conn);
Log.w(MyService.LOG_TAG, "Activity unbindService");
二、Service绑定形式源码分析 1)ContextWrapper#bindService:
/** @path: \\frameworks\\base\\core\\java\\android\\content\\ContextWrapper.java **/
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags)
// @value Context mBase;
return mBase.bindService(service, conn, flags);
和启动形式相仿,接下来调用ContextImpl.bindService;
2) ContextImpl#bindService:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\ContextImpl.java**/
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags)
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, Process.myUserHandle());
3) ContextImpl#bindServiceCommon:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\ContextImpl.java**/
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
UserHandle user)
IServiceConnection sd;
if (conn == null)
throw new IllegalArgumentException("connection is null");
if (mPackageInfo != null)
// 将ServiceConnection封装成为IServiceConnection
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
mMainThread.getHandler(), flags);
else
throw new RuntimeException("Not supported in system context");
validateServiceIntent(service);
try
IBinder token = getActivityToken();
if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
&& mPackageInfo.getApplicationInfo().targetSdkVersion
< Build.VERSION_CODES.ICE_CREAM_SANDWICH)
flags |= BIND_WAIVE_PRIORITY;
service.prepareToLeaveProcess();
// 调用bindService来绑定启动Service
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(),
service, service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, user.getIdentifier());
if (res < 0)
throw new SecurityException(
"Not allowed to bind to service " + service);
return res != 0;
catch (RemoteException e)
return false;
代码中首先将ServiceConnection对象转化成为IServiceConnection。因为Service与客户端建立的连接,可能是跨进程的,系统在绑定Service过程中可能通过IServiceConnection来调用ServiceConnection中的onServiceConnection方法,该过程可能是跨进程的,IServiceConnection是个AIDL文件;
之后再通过ActivityManagerNative.getDefault().bindService来开始绑定Service操作。
先来看第一步,由于mPackageInfo的类型为LoadedApk;
final LoadedApk mPackageInfo;
3.1)LoadedApk#getServiceDispatcher:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\LoadedApk.java**/
public final IServiceConnection getServiceDispatcher(ServiceConnection c, Context context, Handler handler, int flags)
synchronized (mServices)
ServiceDispatcher sd = null;
// 以ServiceConnection为关键字,将ServiceDispatcher与erviceConnection建立关联保存起来
// 还可以看到保存的ArrayMap最终会以Context为关键字保存在一个变量mServices中
/** @value :private final ArrayMap<Context, ArrayMap<ServiceConnection, ServiceDispatcher>> mServices
= new ArrayMap<Context, ArrayMap<ServiceConnection, ServiceDispatcher>>();**/
ArrayMap<ServiceConnection, ServiceDispatcher> map = mServices.get(context);
// 先尝试进行获取
if (map != null)
sd = map.get(c);
// 如果已存在直接返回,未存在则进行创建
if (sd == null)
// 创建一个新的ServiceDispatcher
sd = new ServiceDispatcher(c, context, handler, flags);
// 如果map为空,则创建一个ArrayMap并保存到mServices中
if (map == null)
map = new ArrayMap<ServiceConnection, ServiceDispatcher>();
mServices.put(context, map);
// 将对应的ServiceConnection与ServiceDispatcher保存到一个map中
map.put(c, sd);
else
sd.validate(context, handler);
// 返回一个IServiceConnection类型
return sd.getIServiceConnection();
方法中的参数:
ServiceConnection c == 即Service中自定义的ServiceConnection对象
Context context == 传入的为getOuterContext(),即mOuterContext,ContextImpl类型,指向一个Activity组件
Handler handler == 传入参数为mMainThread.getHandler();
mMainThread的类型为ActivityThread:
final ActivityThread mMainThread;
/** @path: \\frameworks\\base\\core\\java\\android\\app\\ActivityThread.java**/
final H mH = new H();
final Handler getHandler()
return mH;
可以看到最终用来发送启动service消息到主线程的Handler H。
继续来看sd.getIServiceConnection();ServiceDispatcher是LoadedApk的内部类。
先来看ServiceDispatcher的构造函数:
3.2)LoadedApk#ServiceDispatcher#ServiceDispatcher:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\LoadedApk.java**/
static final class ServiceDispatcher
private final InnerConnection mIServiceConnection;
private final ServiceConnection mConnection;
private final Context mContext;
private final Handler mActivityThread;
private final ServiceConnectionLeaked mLocation;
private final int mFlags;
private static class InnerConnection extends IServiceConnection.Stub
final WeakReference<ServiceDispatcher> mDispatcher;
InnerConnection(ServiceDispatcher sd)
mDispatcher = new WeakReference<ServiceDispatcher>(sd);
public void connected(ComponentName name, IBinder service) throws RemoteException
ServiceDispatcher sd = mDispatcher.get();
if (sd != null)
sd.connected(name, service);
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;
可以看到InnerConnection继承了IServiceConnection.Stub,IServiceConnection是个aidl,因此将本地的ServiceConnection封装成为ServiceDispatcher#InnerConnection,可以用以进程间的通信。
3.3)LoadedApk#ServiceDispatcher#getIServiceConnection:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\LoadedApk.java**/
static final class ServiceDispatcher
private final InnerConnection mIServiceConnection;
IServiceConnection getIServiceConnection()
return mIServiceConnection;
getIServiceConnection逻辑较为简单,即是返回新创建的InnerConnection,因此sd的编译时类型为IServiceConnection,运行时类型为ServiceDispatcher.InnerConnection:
分析完ServiceConnection,下面接着分析ActivityManagerNative.getDefault().bindService,由前面得知ActivityManagerNative.getDefault()的类型为AMS的代理:ActivityManagerProxy;则下面调用的是ActivityManagerProxy.bindService;
4、ActivityManagerProxy#bindService: 调用:
ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(),
service, service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, user.getIdentifier());
源代码:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\ActivityManagerNative.java**/
class ActivityManagerProxy implements IActivityManager
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);
// 可以看到将ServiceConnection写入到data中,发送给AMS
data.writeStrongBinder(connection.asBinder());
data.writeInt(flags);
data.writeInt(userId);
// 发送BIND_SERVICE_TRANSACTION IPC通信请求
mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
int res = reply.readInt();
data.recycle();
reply.recycle();
return res;
将前面获取到的sd以Binder方式发送给AMS,并发送 BIND_SERVICE_TRANSACTION IPC通信请求。
接下来到ActivityManagerNative中去处理:
5、ActivityManagerNative#onTransact:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\ActivityManagerNative.java**/
public abstract class ActivityManagerNative extends Binder implements IActivityManager
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException
switch (code)
case BIND_SERVICE_TRANSACTION:
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
IBinder token = data.readStrongBinder();
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
b = data.readStrongBinder();
int fl = data.readInt();
int userId = data.readInt();
IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
// 处理IPC请求函数
int res = bindService(app, token, service, resolvedType, conn, fl, userId);
reply.writeNoException();
reply.writeInt(res);
return true;
接下来使用ActivityManagerNative的子类ActivityManagerService来具体处理该应用请求:
6、ActivityManagerService#bindService:
/** @path: \\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\ActivityManagerService.java**/
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId)
enforceNotIsolatedCaller("bindService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true)
throw new IllegalArgumentException("File descriptors passed in Intent");
synchronized(this)
return mServices.bindServiceLocked(caller, token, service, resolvedType,
connection, flags, userId);
和启动形式一样,最后交给ActiveServices去处理;
7、ActiveServices#bindServiceLocked:
/** @path: \\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\ActiveServices.java**/
int bindServiceLocked(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId)
// 该ProcessRecord描述的是请求绑定该Service组件的Activity组件所运行的应用进程
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
// 获得ActivityRecord用来描述该Activity组件
ActivityRecord activity = null;
if (token != null)
activity = ActivityRecord.isInStackLocked(token);
if (activity == null)
return 0;
.....
// 将待启动的Service组件信息封装成ServiceLookupResult
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
.....
// ServiceRecord用来记录该Service组件的相关信息
ServiceRecord s = res.record;
final long origId = Binder.clearCallingIdentity();
try
.....
// 获得AppBindRecord,表示service对应的组件绑定在callerApp所描述的应用进程中
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
// 用来描述activity对应的Activity组件通过connection绑定到b(AppBindRecord)所对应的应用进程中的Service组件
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent);
IBinder binder = connection.asBinder();
// 因为该Service组件可能被同一应用中的多个Activity组件使用同一个connection来绑定
// 因此该Binder可能对应多个ConnectionRecord对象
ArrayList<ConnectionRecord> clist = s.connections.get(binder);
if (clist == null)
clist = new ArrayList<ConnectionRecord>();
s.connections.put(binder, clist);
clist.add(c);
b.connections.add(c);
if (activity != null)
if (activity.connections == null)
activity.connections = new HashSet<ConnectionRecord>();
activity.connections.add(c);
b.client.connections.add(c);
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0)
b.client.hasAboveClient = true;
if (s.app != null)
updateServiceClientActivitiesLocked(s.app, c, true);
clist = mServiceConnections.get(binder);
if (clist == null)
clist = new ArrayList<ConnectionRecord>();
mServiceConnections.put(binder, clist);
clist.add(c);
if ((flags&Context.BIND_AUTO_CREATE) != 0)
s.lastActivity = SystemClock.uptimeMillis();
// bringUpServiceLocked启动Service组件
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null)
return 0;
......
finally
return 1;
先来看一个函数:retrieveAppBindingLocked:
public AppBindRecord retrieveAppBindingLocked(Intent intent,
ProcessRecord app)
Intent.FilterComparison filter = new Intent.FilterComparison(intent);
IntentBindRecord i = bindings.get(filter);
if (i == null)
i = new IntentBindRecord(this, filter);
bindings.put(filter, i);
// 将ProcessRecord与Service组件建立起关联
AppBindRecord a = i.apps.get(app);
if (a != null)
return a;
a = new AppBindRecord(this, i, app);
i.apps.put(app, a);
return a;
由《Service组件的启动机制深入学习》一文中的分析知,接下来调用bringUpServiceLocked方法来启动Service组件,接着调用realStartServiceLocked在app所描述的进程中启动该Activity组件:
注意realStartServiceLocked中有一步:
8、ActiveServices#realStartServiceLocked:
/** @path: \\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\ActiveServices.java**/
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException
......
try
....
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
....
catch (DeadObjectException e)
finally
....
// 这里执行进行绑定操作
requestServiceBindingsLocked(r, execInFg);
....
可以看到通过scheduleCreateService启动Service组件之后,调用requestServiceBindingsLocked来执行绑定操作,由前面知启动方式的execInfg为false,即不需要绑定;
下面通过 scheduleCreateService启动Service组件的流程和《Service组件的启动机制深入学习》中分析的启动流程相同;接下来分析Service组件启动之后,执行的绑定操作:
9、ActiveServices#requestBindingsLocked:
/** @path: \\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\ActiveServices.java**/
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
// 由前面知,r.bindings中保存了一系列Service组件和app之间的绑定关系
for (int i=r.bindings.size()-1; i>=0; i--)
// 执行遍历,将Service绑定到这些ProcessRecord中
IntentBindRecord ibr = r.bindings.valueAt(i);
if (!requestServiceBindingLocked(r, ibr, execInFg, false))
break;
10、 ActiveServices#requestBindingsLocked:
/** @path: \\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\ServiceRecord.java**/
private final boolean requestServiceBindingLocked(ServiceRecord r,
IntentBindRecord i, boolean execInFg, boolean rebind)
if (r.app == null || r.app.thread == null)
// If service is not currently running, can't yet bind.
return false;
// rebind参数用以标示是否需要重新绑定
if ((!i.requested || rebind) && i.apps.size() > 0)
try
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
// 接下来调用scheduleBindService去绑定Service组件
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
if (!rebind)
i.requested = true;
i.hasBound = true;
i.doRebind = false;
catch (RemoteException e)
if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
return false;
return true;
代码逻辑较为简单,需要重新绑定或者i.apps中仍然有为执行完的绑定任务,都继续调用scheduleBindService来执行绑定任务;
r.app.thread的实际运行时类型为ApplicationThreadProxy。
11、 ApplicationThreadProxy#scheduleBindService:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\ApplicationThreadNative.java**/
class ApplicationThreadProxy implements IApplicationThread
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind,
int processState) throws RemoteException
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
intent.writeToParcel(data, 0);
data.writeInt(rebind ? 1 : 0);
data.writeInt(processState);
mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
发送一个 SCHEDULE_BIND_SERVICE_TRANSACTION类型的IPC请求;
12、ApplicationThreadNative#onTransact:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\ApplicationThreadNative.java**/
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException
switch (code)
case SCHEDULE_BIND_SERVICE_TRANSACTION:
data.enforceInterface(IApplicationThread.descriptor);
IBinder token = data.readStrongBinder();
Intent intent = Intent.CREATOR.createFromParcel(data);
boolean rebind = data.readInt() != 0;
int processState = data.readInt();
scheduleBindService(token, intent, rebind, processState);
return true;
可以看到接下里调用子类ApplicationThread的scheduleBindService;
13:ApplicationThread#scheduleBindService:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\ActivityThread.java**/
private class ApplicationThread extends ApplicationThreadNative
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);
类似得,通过H发送一个BIND_SERVICE请求,直接来看响应函数;
14、H:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\ActivityThread.java**/
private class H extends Handler
public static final int BIND_SERVICE = 121;
void handleMessage(Message msg)
switch (msg.what)
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
private void handleBindService(BindServiceData data)
// data.token指向了一个ServiceRecord
// 由启动过程知,mServices保存了所有启动后的Service,这里通过data.token关键字进行获取
Service s = mServices.get(data.token);
if (s != null)
try
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try
if (!data.rebind)
// 可以看到这里就是自定义Service时重写的onBind函数
IBinder binder = s.onBind(data.intent);
// 继续通过publishService来实现
ActivityManagerNative.getDefault().publishService(
data.token, data.intent, binder);
else // 调用rebind情况
s.onRebind(data.intent);
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
ensureJitEnabled();
catch (RemoteException ex)
catch (Exception e)
.......
可以看到系统先根据 data.token为关键字,获取相应的Service,然后调用onBind,这里的onBind即是在自定义Service中重写的onBind方法,获取该方法中返回的Binder对象。
然后继续调用ActivityManagerNative.getDefault().publishService来处理;
由前面易知ActivityManagerNative.getDefault()的实际类型为ActivityManagerProxy:
15、ActivityManagerProxy#publishService:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\ActivityManagerNative.java**/
class ActivityManagerProxy implements IActivityManager
public void publishService(IBinder token,
Intent intent, IBinder service) throws RemoteException
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
intent.writeToParcel(data, 0);
data.writeStrongBinder(service);
mRemote.transact(PUBLISH_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
发送一个 PUBLISH_SERVICE_TRANSACTION类型的IPC请求给AMS;
中间跳转过程省略,AMS处理PUBLISH_SERVICE_TRANSACTION类型请求的方法为:ActivityManagerService.publishService
16、ActivityManagerService#publishService:
public void publishService(IBinder token, Intent intent, IBinder service)
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors() == true)
throw new IllegalArgumentException("File descriptors passed in Intent");
synchronized(this)
if (!(token instanceof ServiceRecord))
throw new IllegalArgumentException("Invalid service token");
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
这里会首先判断传入的参数是否为ServiceRecord,如果不是,则直接报错;
然后交托给ActiveServices的publishServiceLocked去处理;
17、ActiveServices#publishServiceLocked:
/** @path: \\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\ActiveServices.java**/
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service)
final long origId = Binder.clearCallingIdentity();
try
if (r != null)
Intent.FilterComparison filter
= new Intent.FilterComparison(intent);
// 获得对应的IntentBindRecord对象
IntentBindRecord b = r.bindings.get(filter);
if (b != null && !b.received)
b.binder = service;
b.requested = true;
b.received = true; // 用来表示Services组件是否已经传递给AMS了,如果否则进入此处理函数中
for (int conni=r.connections.size()-1; conni>=0; conni--)
// 获取ConnectionRecord
ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
for (int i=0; i<clist.size(); i++)
ConnectionRecord c = clist.get(i);
if (!filter.equals(c.binding.intent.intent))
continue;
try
// c.conn是InnerConnection对象,调用其connected函数来进行连接
c.conn.connected(r.name, service);
catch (Exception e)
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
finally
Binder.restoreCallingIdentity(origId);
可以看到代码中主要的是获取到之前保存的
ConnectionRecord对象,然后调用其conn变量(InnerConnection对象,其实际类型为自定义的ServiceConnection封装成的ServiceDispatcher.ServiceConnection)的connected方法进行连接;
同时可以看到同一个ServiceConnection只会连接一次,因为ConnectionRecord对象的received变量会置为true,下一调用onBind时,并不会继续跳入到绑定逻辑代码中执行connect操作;
18、LoadedApk#ServiceDispatcher#InnerConnection#connected:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\LoadedApk.java**/
static final class ServiceDispatcher
private static class InnerConnection extends IServiceConnection.Stub
final WeakReference<ServiceDispatcher> mDispatcher;
InnerConnection(ServiceDispatcher sd)
mDispatcher = new WeakReference<ServiceDispatcher>(sd);
public void connected(ComponentName name, IBinder service) throws RemoteException
ServiceDispatcher sd = mDispatcher.get();
if (sd != null)
sd.connected(name, service);
最终又会去调用 ServiceDispatcher的connected函数;
19、LoadedApk#ServiceDispatcher#connected:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\LoadedApk.java**/
static final class ServiceDispatcher
public void connected(ComponentName name, IBinder service)
if (mActivityThread != null)
mActivityThread.post(new RunConnection(name, service, 0));
else
doConnected(name, service);
由前面知mActivityThread变量即为H,这里将一个RunConnection发送到主线程中去运行;
20、RunConnection:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\LoadedApk.java**/
static final class ServiceDispatcher
private final class RunConnection implements Runnable
RunConnection(ComponentName name, IBinder service, int command)
mName = name;
mService = service;
mCommand = command;
public void run()
// 根据命令的不同,执行绑定和取消绑定操作
if (mCommand == 0)
doConnected(mName, mService);
else if (mCommand == 1)
doDeath(mName, mService);
final ComponentName mName;
final IBinder mService;
final int mCommand;
RunConnection是一个Runnable,其具体的执行逻辑在run中,根据命令Command的不同,执行绑定和取消绑定操作;由19步值,command为0,则执行doConnected;
21、ServiceDispatcher#doConnected:
/** @path: \\frameworks\\base\\core\\java\\android\\app\\LoadedApk.java**/
static final class ServiceDispatcher
private final ServiceConnection mConnection;
public void doConnected(ComponentName name, IBinder service)
.......
// If there is a new service, it is now connected.
if (service != null)
mConnection.onServiceConnected(name, service);
public void doDeath(ComponentName name, IBinder service)
mConnection.onServiceDisconnected(name);
ServiceDispatcher中保存了在代码中自定义的ServiceConnection,这里的绑定工作即是通过调用其onServiceConnected 来完成;
22、自定义的ServiceConnection:
// 定义ServiceConnection
private ServiceConnection conn = new ServiceConnection()
@Override
public void onServiceConnected(ComponentName name, IBinder service)
// 通过定义的Binder来获取Service实例来供使用
mService = ((MyService.MyBinder) service).getService();
Log.w(MyService.LOG_TAG, "Activity onServiceConnected");
@Override
public void onServiceDisconnected(ComponentName name)
mService = null;
// 当Service被意外销毁时
Log.w(MyService.LOG_TAG, "Activity onServiceDisconnected");
;
接下来就可以根据获取到的Service实例来直接对Service进行操作;
以上是关于Service绑定形式启动过程的主要内容,如果未能解决你的问题,请参考以下文章