美文网首页
Service 源码看启动过程

Service 源码看启动过程

作者: johnnycmj | 来源:发表于2017-08-18 18:55 被阅读29次

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

    相关文章

      网友评论

          本文标题:Service 源码看启动过程

          本文链接:https://www.haomeiwen.com/subject/hwaarxtx.html