Service 源码看启动过程

2017-08-18  本文已影响29人  johnnycmj

Service两次IPC过程

service_ipc.png

Service 启动

我们知道开启Service有两种,一种是 直接startService(intent); 另外一种是bindService(intent,mConn, Service.BIND_AUTO_CREATE);

startService()

先看看startService()是如果启动Service。在Activity中直接startService(),是直接ContextWapper中的startService(Intent service)。

ContextWapper.java

@Override
public ComponentName startService(Intent service) {
    return mBase.startService(service);
}

这里的 mBase 是在Activity启动的时候通过 attachBaseContext进来的一个Context的实现,实际上是ContextImpl
也就是说实际上是调用ContextImpl中的startService(service)。

ContextImpl.java

@Override
public ComponentName startService(Intent service) {
    //判断警告是否是系统进程直接调用方法。
    warnIfCallingFromSystemProcess();
    return startServiceCommon(service, mUser);
}

private ComponentName startServiceCommon(Intent service, UserHandle user) {
    try {
        //验证service是否为空。
        validateServiceIntent(service);
        //准备intent leave app process。
        service.prepareToLeaveProcess();

        //正在启动的是通过AMS启动.
        ComponentName cn = ActivityManagerNative.getDefault().startService(
            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                        getContentResolver()), getOpPackageName(), user.getIdentifier());
        if (cn != null) {
            if (cn.getPackageName().equals("!")) {
                throw new SecurityException(
                        "Not allowed to start service " + service
                        + " without permission " + cn.getClassName());
            } else if (cn.getPackageName().equals("!!")) {
                throw new SecurityException(
                        "Unable to start service " + service
                        + ": " + cn.getClassName());
            }
        }
        return cn;
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
}

这边通过ContextImpl中的startService(service)最后调用startServiceCommon()的方法。
注意startServiceCommon()中的ActivityManagerNative.getDefault().startService() 我们看一下ActivityManagerNative 是什么东西.

ActivityManagerNative类的定义是这样的:

public abstract class ActivityManagerNative extends Binder implements IActivityManager{}

这边ActivityManagerNative是一个典型的Binder对象,继承Binder并实现一个接口。这边如果不理解Binder,建议先去学习了解Binder,了解Android的IPC机制。4大组件底层的启动大部分都是通过Binder进行关联启动。

如果了解Binder,那我们继续下去,我们在写AIDL的时候,IDE自动帮我们生成Binder代码,我们知道Binder有两个内容,一个是Stub,用来服务端通信的,还有一个Proxy代理用来客户端信息。而ActivityManagerNative本身就是一个Stub,它是由Google自己写的一个Binder。ActivityManagerNative 里面也有一个Proxy。就是ActivityManagerProxy。

class ActivityManagerProxy implements IActivityManager{
    private IBinder mRemote;

    public ActivityManagerProxy(IBinder remote)
    {
        mRemote = remote;
    }

    public IBinder asBinder()
    {
        return mRemote;
    }
    
    .....
    
}

看这个跟IDE自动生成的代码是一样的。
我们接着上面的分析,在ContextImpl中ActivityManagerNative.getDefault(),实际上是一由一个自己封装Singleton单例对象。在get()的时候如果是第一次则会调用create().

static public IActivityManager getDefault() {
    return gDefault.get();
}

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

Singleton.java

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

在这里将获取的IBinder转成IActivityManager 对象。ActivityManagerNative.getDefault().startService()实际上是调用IActivityManager.startService(). 由上面分析的Binder,我们可以知道IActivityManager.startService()就是从客户端调用startService,也就是在Proxy里面调用startService()。

ActivityManagerProxy.startService:

public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, 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.writeString(callingPackage);
    data.writeInt(userId);
    mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
    reply.readException();
    ComponentName res = ComponentName.readFromParcel(reply);
    data.recycle();
    reply.recycle();
    return res;
}

注意这句:mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
通过transact调用Binder的服务端的方法。

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
    ...
    
    case START_SERVICE_TRANSACTION: {
        data.enforceInterface(IActivityManager.descriptor);
        IBinder b = data.readStrongBinder();
        IApplicationThread app = ApplicationThreadNative.asInterface(b);
        Intent service = Intent.CREATOR.createFromParcel(data);
        String resolvedType = data.readString();
        String callingPackage = data.readString();
        int userId = data.readInt();
        ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
        reply.writeNoException();
        ComponentName.writeToParcel(cn, reply);
        return true;
    }
    ...
    
    }
}

这里的startService(app, service, resolvedType, callingPackage, userId);具体实现实际上有ActivityManagerService子类实现的。

ActivityManagerService.java

@Override
public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, String callingPackage, int userId)
        throws TransactionTooLargeException {
    enforceNotIsolatedCaller("startService");
    // Refuse possible leaked file descriptors
    if (service != null && service.hasFileDescriptors() == true) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }

    if (callingPackage == null) {
        throw new IllegalArgumentException("callingPackage cannot be null");
    }

    if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
            "startService: " + service + " type=" + resolvedType);
    synchronized(this) {
        final int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        ComponentName res = mServices.startServiceLocked(caller, service,
                resolvedType, callingPid, callingUid, callingPackage, userId);
        Binder.restoreCallingIdentity(origId);
        return res;
    }
}

接着调用mServices.startServiceLocked()方法,mServices是ActiveServices。

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, String callingPackage, int userId)
            throws TransactionTooLargeException {
          
    ....
    
    return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}

startServiceInnerLocked:

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
 ....
 
  String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
    if (error != null) {
        return new ComponentName("!!", error);
    }
    
    ...
}

这里调用bringUpServiceLocked,而在它的内部实际调用了realStartServiceLocked()方法。

private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting) throws TransactionTooLargeException {
      
    ...
    if (!isolated) {
        ...
        try {
            app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
            realStartServiceLocked(r, app, execInFg);
            return null;
        } catch (TransactionTooLargeException e) {
            throw e;
        } catch (RemoteException e) {
          
    }
    ...
}

看一下realStartServiceLocked():

 private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
            
    if (app.thread == null) {
            throw new RemoteException();
    } 
    
    try {
        ...
        //回调onCreate
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
        ...
    }
    
    ...
    //回调onStartCommand
    sendServiceArgsLocked(r, execInFg, true);
    ...
                
}

这边重点看app.thread.scheduleCreateService() ,这里的app.thread是IApplicationThread。而在ActivityManagerNative里的START_SERVICE_TRANSACTION有这句:
IApplicationThread app = ApplicationThreadNative.asInterface(b); 我们的这个app.thread也是ApplicationThreadNative里的Binder。这边又是一个Binder对象。

同样ApplicationThreadNative也是一个Stub,里面的ApplicationThreadProxy是一个Proxy。所以这里app.thread.scheduleCreateService()实际是ApplicationThreadNative.scheduleCreateService().

 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);
    try {
        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
    } catch (TransactionTooLargeException e) {
        Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info);
        throw e;
    }
    data.recycle();
}

调用 mRemote.transact(),则回调Proxy里的SCHEDULE_CREATE_SERVICE_TRANSACTION这个code。

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    
    ...
    case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
        data.enforceInterface(IApplicationThread.descriptor);
        IBinder token = data.readStrongBinder();
        ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
        CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
        int processState = data.readInt();
        scheduleCreateService(token, info, compatInfo, processState);
        return true;
    }
    ...
}

ApplicationThreadNative的具体实现是ApplicationThread:

private class ApplicationThread extends ApplicationThreadNative {
    ...
    
    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);
    }
    ...
}

这边通过sendMessage()发送消息,由H来处理,H是系统的Handler。

private class H extends Handler {
    public void handleMessage(Message msg) {
        ...
        case CREATE_SERVICE:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
            handleCreateService((CreateServiceData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        
        ...
    }
}

在这里接着调用handleCreateService()。

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 = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

            //创建ContextImpl对象。
            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,
                    ActivityManagerNative.getDefault());
            //这里就是最终调用onCreate().
            service.onCreate();
            mServices.put(data.token, service);
            try {
                //至此调用服务完成.
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                // nothing to do.
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

}

到这里Service的onCreate()方法回调了。按照Service的生命周期,用startService方式启动Service接着会调用onStartCommand(),那这个是在哪里回调的?其实是在realStartServiceLocked()里的sendServiceArgsLocked

private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {
    
    ...
     while (r.pendingStarts.size() > 0) {
        ...
        try {
            ...
            r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
        }
        ...
     }
}

同样到了ApplicationThread的scheduleServiceArgs().

public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
    int flags ,Intent args) {
    ServiceArgsData s = new ServiceArgsData();
    s.token = token;
    s.taskRemoved = taskRemoved;
    s.startId = startId;
    s.flags = flags;
    s.args = args;

    sendMessage(H.SERVICE_ARGS, s);
}

这样就又到了H里面了

 case SERVICE_ARGS:
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
        handleServiceArgs((ServiceArgsData)msg.obj);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        break;
private void handleServiceArgs(ServiceArgsData data) {
    Service s = mServices.get(data.token);
    if (s != null) {
        try {
            if (data.args != null) {
                data.args.setExtrasClassLoader(s.getClassLoader());
                data.args.prepareToEnterProcess();
            }
            int res;
            if (!data.taskRemoved) {
                //至此onStartCommand 回调完成。
                res = s.onStartCommand(data.args, data.flags, data.startId);
            } else {
                s.onTaskRemoved(data.args);
                res = Service.START_TASK_REMOVED_COMPLETE;
            }

            QueuedWork.waitToFinish();

            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
            } catch (RemoteException e) {
                // nothing to do.
            }
            ensureJitEnabled();
        } catch (Exception e) {
            if (!mInstrumentation.onException(s, e)) {
                throw new RuntimeException(
                        "Unable to start service " + s
                        + " with " + data.args + ": " + e.toString(), e);
            }
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读