Android四大组件Service启动源码分析

来源:互联网 发布:上古卷轴5优化工具 编辑:程序博客网 时间:2024/06/05 08:40

1 用法


启动状态

Intent intent=new Intent(this,MyService.class);

startService(intent);


绑定状态

Intent intent=new Intent(this,MyService.class);

bindService(intent,mServiceConnection,BIND_AUTO_CREATE);


private ServiceConnection mServiceConnection= new ServiceConnection() {  
    // 当与service的连接建立后被调用  
    public void onServiceConnected(ComponentName className, IBinder service) {  
        //TODO
    }  
  
    // 当与service的连接意外断开时被调用  
    public void onServiceDisconnected(ComponentName className) {  
       //TODO
    }  
};  



2 源码分析


(1)先看启动状态

service启动状态时序图如下


1  ContextWrapper

    public ComponentName startService(Intent service) {        return mBase.startService(service);    }
Service的启动从ContextWrapper的startService开始,mBase是ContextImpl类,Activity通过attach方法和ContextImpl关联起来。以后会详细讲解Context族谱的关系。所以重点在ContextImpl中的startService方法中。


2 ContextImpl

@Override public ComponentName startService(Intent service) {        warnIfCallingFromSystemProcess();        return startServiceCommon(service, mUser);    }private ComponentName startServiceCommon(Intent service, UserHandle user) {.....            ComponentName cn = ActivityManagerNative.getDefault().startService(                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(                            getContentResolver()), getOpPackageName(), user.getIdentifier());        .....            return cn;            }
Activity篇分析过,ActivityManagerNative.getDefault()获得了ActivityManagerProxy(ActivityManagerNative的内部类),ActivityManagerProxy的startService真正是在AMS中执行


3  ActivityManagerProxy

public ComponentName startService(IApplicationThread caller, Intent service,            String resolvedType, int userId) throws RemoteException    {        Parcel data = Parcel.obtain();        Parcel reply = Parcel.obtain();        data.writeInterfaceToken(IActivityManager.descriptor);        data.writeStrongBinder(caller != null ? caller.asBinder() : null);        service.writeToParcel(data, 0);        data.writeString(resolvedType);        data.writeInt(userId);        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);        reply.readException();        ComponentName res = ComponentName.readFromParcel(reply);        data.recycle();        reply.recycle();        return res;    }

4  ActivityManagerService

public ComponentName startService(IApplicationThread caller, Intent service,            String resolvedType, int userId) {        ......            ComponentName res = mServices.startServiceLocked(caller, service,                    resolvedType, callingPid, callingUid, userId);        ......            return res;        }    }

ActivityManagerService的startService方法中,mServices是一个ActiveServices类,用于辅助AMS管理Service,类似于管理Activity的ActivityStakSupervisor。


5 ActiveServices

private final void realStartServiceLocked(ServiceRecord r,            ProcessRecord app, boolean execInFg) throws RemoteException {        ......            app.thread.scheduleCreateService(r, r.serviceInfo,                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),                    app.repProcState);            r.postNotification();            created = true;        ......        sendServiceArgsLocked(r, execInFg, true);        ......    }
mServices.startServiceLocked执行一系列方法后,最后在realStartServiceLocked真正创建了service实例。类似Activity篇,app.thread是ApplicationThreadProxy,ServiceRecord是记录Service的数据结构。

6  ApplicationThreadProxy(ApplicationThreadNative内部类)

public final void scheduleCreateService(IBinder token, ServiceInfo info,            CompatibilityInfo compatInfo, int processState) throws RemoteException {        Parcel data = Parcel.obtain();        data.writeInterfaceToken(IApplicationThread.descriptor);        data.writeStrongBinder(token);        info.writeToParcel(data, 0);        compatInfo.writeToParcel(data, 0);        data.writeInt(processState);        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,                IBinder.FLAG_ONEWAY);        data.recycle();    }
和Activity篇一样,这里是一个binder通信,ApplicationThreadProxy和ApplicationThread的通信,所以真正的执行在ApplicationThread的scheduleCreateService中

7  ApplicationThread(ActivityThread内部类)

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);        }

8 ActivityThread

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {        ......        mH.sendMessage(msg);    }
很显然,这个过程和Activity的启动过程类似,都是通过发送消息给Handler H来完成。
private class H extends Handler {    ......        public void handleMessage(Message msg) {            switch (msg.what) {                case LAUNCH_ACTIVITY: {                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;                    r.packageInfo = getPackageInfoNoCheck(                            r.activityInfo.applicationInfo, r.compatInfo);                    handleLaunchActivity(r, null);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                } break;               ......                case CREATE_SERVICE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");                    handleCreateService((CreateServiceData)msg.obj);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case BIND_SERVICE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");                    handleBindService((BindServiceData)msg.obj);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case UNBIND_SERVICE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");                    handleUnbindService((BindServiceData)msg.obj);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case SERVICE_ARGS:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");                    handleServiceArgs((ServiceArgsData)msg.obj);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case STOP_SERVICE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");                    handleStopService((IBinder)msg.obj);                    maybeSnapshot();                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;               ......        }    }
这里进入CREATE_SERVICE分支,执行了handleCreateService方法,所以重点在handleCreateService方法中
private void handleCreateService(CreateServiceData data) {              LoadedApk packageInfo = getPackageInfoNoCheck(                data.info.applicationInfo, data.compatInfo);        Service service = null;  //首先通过类加载器创建了Service的实例            java.lang.ClassLoader cl = packageInfo.getClassLoader();            service = (Service) cl.loadClass(data.info.name).newInstance();        .....//接着创建了ContextImpl对象,并通过Service的attach方法建立了二者的关系            ContextImpl context = new ContextImpl();            context.init(packageInfo, null, this);                Application app = packageInfo.makeApplication(false, mInstrumentation);            context.setOuterContext(service);            service.attach(context, this, data.info.name, data.token, app,                    ActivityManagerNative.getDefault());
//最后调用Service的onCreate方法并将Service对象存储到mServices中 service.onCreate(); mServices.put(data.token, service)
这里涉及到LoadedApk ,ClassLoader ,ContextImpl,mServices
final ArrayMap<IBinder, Service> mServices
            = new ArrayMap<IBinder, Service>();
这里Service的启动状态就分析完了



(2)绑定状态


和Service启动状态一样,绑定状态也是从ContextWrapper开始

1 ContextWrapper

@Override    public boolean bindService(Intent service, ServiceConnection conn,            int flags) {        return mBase.bindService(service, conn, flags);    }
mBase是ContextImpl,上面已经说过了。


2 ContextImpl
ContextImpl的bindService最终会调用到自己的bindServiceCommon

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,            UserHandle user) {        IServiceConnection sd;        //这里将客户端的ServiceConnection转化为ServiceDispatcher。InnerConnection对象        //之所以要转化,因为这里可能涉及到跨进程          if (mPackageInfo != null) { sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),      mMainThread.getHandler(), flags); }       ......       int res = ActivityManagerNative.getDefault().bindService( mMainThread.getApplicationThread(),         getActivityToken(), service, service.resolveTypeIfNeeded(getContentResolver()       ), sd, flags, getOpPackageName(), user.getIdentifier());         ...... }


3  LoadedApk
这里,mPackageInfo是个LoadedApk类,从getServiceDispatcher方法可看出,map中保存了客户端conn和LoadedApk.ServiceDispatcher的一份映射,首先在map查找是否有相应的conn,没有就创建一个ServiceDispatcher,并放入mServices中
public final IServiceConnection getServiceDispatcher(ServiceConnection c,            Context context, Handler handler, int flags) {        synchronized (mServices) {            LoadedApk.ServiceDispatcher sd = null;            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);            if (map != null) {                sd = map.get(c);            }            if (sd == null) {                sd = new ServiceDispatcher(c, context, handler, flags);                if (map == null) {                    map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();                    mServices.put(context, map);                }                map.put(c, sd);            } else {                sd.validate(context, handler);            }            return sd.getIServiceConnection();        }    }
sd.getIServiceConnection得到ServiceDispatcher.InnerConnection实例。InnerConnection是一个binder,是一个IServiceConnection类型(这里的InnerConnection不是代理,是真正的binder)
mServices的类型
    private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
        = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();
这里涉及到ServiceConnection,LoadedApk,ServiceDispatcher,InnerConnection,详细讲解下他们的关系


4  ServiceDispatcher(LoadedApk内部类)

getServiceDispatcher方法中,如果mServices不存在客户端conn,就创建ServiceDispatcher,sd = new ServiceDispatcher(c, context, handler, flags);

 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;        } IServiceConnection getIServiceConnection() {            return mIServiceConnection;        }
5  InnerConnection(ServiceDispatcher内部类)

ServiceDispatcher构造函数中会创建一个InnerConnection实例,从IServiceConnection.Stub可以看出,InnerConnection是一个binder

  private static class InnerConnection extends IServiceConnection.Stub {            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;            InnerConnection(LoadedApk.ServiceDispatcher sd) {                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);            }            public void connected(ComponentName name, IBinder service) throws RemoteException {                LoadedApk.ServiceDispatcher sd = mDispatcher.get();                if (sd != null) {                    sd.connected(name, service);                }            }        }

6  ActivityManagerProxy

回到ContextImpl,3-4-5步只是将客户端ServiceConnection转化为InnerConnection(binder),接下来是重点,ActivityManagerNative.getDefault().bindService

   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;    }

7 ActivityManagerService

按部就班,从ActivityManagerProxy的bindService    到   ActivityManagerService的bindService

 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);        }    }


8 ActiveServices

mServices是ActiveServices类型,mServices.bindServiceLocked执行经过一系列方法,最后又到了realStartServiceLocked方法

  private final void realStartServiceLocked(ServiceRecord r,            ProcessRecord app, boolean execInFg) throws RemoteException {        .......//startService启动方式            app.thread.scheduleCreateService(r, r.serviceInfo,                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),                    app.repProcState);        ......//bindService启动方式        requestServiceBindingsLocked(r, execInFg);......        //onStartCommand        sendServiceArgsLocked(r, execInFg, true);......    }
和启动service是通过app.thread.scheduleCreateService不同,绑定service是通过requestServiceBindingsLocked执行

private final boolean requestServiceBindingLocked(ServiceRecord r,            IntentBindRecord i, boolean execInFg, boolean rebind) {        ......                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,                        r.app.repProcState);                ......        return true;    }
app.thread出现多次了,ApplicationThreadProxy!   ApplicationThreadProxy!    ApplicationThreadProxy!重要的事说三遍。

9 ApplicationThreadProxy(ApplicationThreadNative内部类)

 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();    }


10  ApplicationThread
 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;            if (DEBUG_SERVICE)                Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="                        + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());            sendMessage(H.BIND_SERVICE, s);        }


11  ActivityThread

又到了我们最熟悉的地方了,贴代码,不想说

  private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {        if (DEBUG_MESSAGES) Slog.v(            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)            + ": " + arg1 + " / " + obj);        Message msg = Message.obtain();        msg.what = what;        msg.obj = obj;        msg.arg1 = arg1;        msg.arg2 = arg2;        if (async) {            msg.setAsynchronous(true);        }        mH.sendMessage(msg);    }
private class H extends Handler {    ......        public void handleMessage(Message msg) {            switch (msg.what) {                case LAUNCH_ACTIVITY: {                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;                    r.packageInfo = getPackageInfoNoCheck(                            r.activityInfo.applicationInfo, r.compatInfo);                    handleLaunchActivity(r, null);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                } break;               ......                case CREATE_SERVICE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");                    handleCreateService((CreateServiceData)msg.obj);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case BIND_SERVICE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");                    handleBindService((BindServiceData)msg.obj);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case UNBIND_SERVICE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");                    handleUnbindService((BindServiceData)msg.obj);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case SERVICE_ARGS:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");                    handleServiceArgs((ServiceArgsData)msg.obj);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;                case STOP_SERVICE:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");                    handleStopService((IBinder)msg.obj);                    maybeSnapshot();                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;               ......        }    }
BIND_SERVICE对应于handleBindService

private void handleBindService(BindServiceData data) {        Service s = mServices.get(data.token);             ......                data.intent.setExtrasClassLoader(s.getClassLoader());                    if (!data.rebind) {                        IBinder binder = s.onBind(data.intent);                        ActivityManagerNative.getDefault().publishService(                                data.token, data.intent, binder);                    } else {                        s.onRebind(data.intent);                        ActivityManagerNative.getDefault().serviceDoneExecuting(                                data.token, 0, 0, 0);                    }                    ensureJitEnabled();               ......                  }    }

在第8步realStartServiceLocked方法中app.thread.scheduleCreateService会创建service,这个在启动模式中已经分析过了。还记得创建service时会把service放入mServices中吗?再次回顾下ActivityThread的方法handleCreateService

private void handleCreateService(CreateServiceData data) {       ......        LoadedApk packageInfo = getPackageInfoNoCheck(                data.info.applicationInfo, data.compatInfo);        Service service = null;            java.lang.ClassLoader cl = packageInfo.getClassLoader();            service = (Service) cl.loadClass(data.info.name).newInstance();                            ContextImpl context = new ContextImpl();            context.init(packageInfo, null, this);            Application app = packageInfo.makeApplication(false, mInstrumentation);            context.setOuterContext(service);            service.attach(context, this, data.info.name, data.token, app,                    ActivityManagerNative.getDefault());            //mService存储创建的service            mServices.put(data.token, service);           }
再次看看mServices

final ArrayMap<IBinder, Service> mServices            = new ArrayMap<IBinder, Service>();
复习完毕,现在再来看handleBindService,Service s = mServices.get(data.token);,从mServices中获取Service对象,然后调用s.onBind()。

到这里为止,已经创建了service实例,并且调用了service的方法onBind(),但是此时客户端(通常是Activity)还没有连接到service,所以还要调用客户端的serviceConnection中的onServiceConnected,这个过程是由ActivityManagerNative.getDefault().publishService来完成,ActivityManagerNative.getDefault()就是ActivityManagerProxy!   ActivityManagerProxy!    ActivityManagerProxy!,重要的事说三遍!

12  ActivityManagerProxy

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();    }

真正的执行过程在AMS中


13 ActivityManagerService

 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);        }    }
又见到mServices了,这个ActiveServices类是服务端AMS管理service的助手


14 ActiveServices

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {                ......    ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);                ......    ConnectionRecord c = clist.get(i);                ......   c.conn.connected(r.name, service); ...... }

15 InnerConnection (LoadedApk内部类ServiceDispathcer中的内部类)

ConnectionRecord 就是记录客户端(Activity)中connection的数据结构,客户端的connection经过3->4->5转化为InnerConnection,即一个binder,用于跨进程通信。

 private static class InnerConnection extends IServiceConnection.Stub {            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;            InnerConnection(LoadedApk.ServiceDispatcher sd) {                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);            }            public void connected(ComponentName name, IBinder service) throws RemoteException {                LoadedApk.ServiceDispatcher sd = mDispatcher.get();                if (sd != null) {                    sd.connected(name, service);                }            }        }
c.conn.connected中调用了sd.connected,即调用了ServiceDispatcher 的connected方法


16  ServiceDispatcher 

public void connected(ComponentName name, IBinder service) {            if (mActivityThread != null) {                mActivityThread.post(new RunConnection(name, service, 0));            } else {                doConnected(name, service);            }        }
这里涉及到mActivityThread(Handler),注意一下,将客户端connection转化为binder是在客户端内进行的,也就是说3->4->5步是在客户端进行的,LoadedApk相关的类的执行都是在客户端执行的。还记得第2步吗?

mActivityThread就是ActivityThread中的Handler H,new RunConnection(name, service, 0)方法经过mActivityThread.post就运行在主线程中

 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;        }

  public void doConnected(ComponentName name, IBinder service) {                        ......                mConnection.onServiceDisconnected(name);                       if (service != null) {                mConnection.onServiceConnected(name, service);            }        }
因为ServiceDispatcher保存了客户端的connection对象,所以可以调用onServiceConnected。在第4步就保存了。到这里客户端(Activity)就和服务端关联了。




3 总结






1 0
原创粉丝点击