• Service的启动流程源码跟踪


    前言:

    当我们在一个Activity里面startService的时候,具体的执行逻辑是怎么样的?需要我们一步步根据源码阅读。
    

    在阅读源码的时候,要关注思路,不要陷在具体的实现细节中,一步步整理代码的思路。

    注:源码使用Api 25的

    1.起点:Activity-> startService

    在Activity中没有找到startService的方法,
    查看Activity的继承关系:
    Context->ContextWrapper->ContextThemeWrapper->Activity
    回溯到ContextWrapper中,找到了startService()的方法:

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

    从ContextWrapper的命名和方法的实现上,我们可以猜到其实ContextWrapper只是一个包装
    真正实现startService逻辑的是调用mBase.startService(service);
    其中
    Context mBase;是一个成员变量
    由于Context是一个抽象类,startService是它的抽象方法,所以一定存在一个Context的子类实现了Context的抽象方法。
    其实就是ContextImpl类,所以Context的抽象方法的具体实现由ContextImpl负责,其他Context的子类只需要在自己的方法里面调用
    ContextImpl的即可。

    2.ContextImpl ->startService(Intent service)

       @Override
        public ComponentName startService(Intent service) {
            warnIfCallingFromSystemProcess();
            return startServiceCommon(service, mUser);
        }

    调用到startServiceCommon(service, mUser)

        private ComponentName startServiceCommon(Intent service, UserHandle user) {
            try {
                validateServiceIntent(service);
                service.prepareToLeaveProcess(this);
                ComponentName cn = ActivityManagerNative.getDefault().startService(
                    mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                                getContentResolver()), getOpPackageName(), user.getIdentifier());
             //省略部分代码
                }
                return cn;
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

    可以看到是调用ActivityManagerNative的 ActivityManagerNative.getDefault().startService方法

    3.ActivityManagerNative-> ActivityManagerNative.getDefault().startService

    观察public abstract class ActivityManagerNative extends Binder implements IActivityManager的定义
    可以猜测这是一个可以Binder进程IPC操作的类。
    PS:如果你对Binder还很陌生推荐你先了解Binder,不需要深入到底层实现,不过Java层的基本用法需要了解
    下面的博客都可以参考:
    weishu的博客
    Gityuan的博客
    引用一个对Binder很精彩的描述:
    Binder使得一个进程A有一个真身,它实现了具体的逻辑,然后其他进程获得的是Binder的影子(或者说是引用?句柄?)
    然后其他进程通过Binder的影子调用就仿佛调用了A的真身的操作。
    其实很多资料都告诉我们启动四大组件是IPC的操作,app进程必须通过IPC与另外的进程通信,完成四大组件的启动。
    结合上面的描述,我们知道,那么app进程的是影子。我们找到它:
    在ActivityManagerNative它有一个子类:

    class ActivityManagerProxy implements IActivityManager{
    //省略代码
      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);//挂起,通过Binder驱动IPC
            reply.readException();
            ComponentName res = ComponentName.readFromParcel(reply);
            data.recycle();
            reply.recycle();
            return res;
        }
    //省略代码
    }

    这就是影子,我们在App进程调用的startService最终会到达这里,然后经过Binder驱动的一系列操作到达另外一个进程的真身

    所以:ActivityManagerNative.getDefault()这里获取的应该就是ActivityManagerProxy 的实例,我们看一下它的实现:

    static public IActivityManager getDefault() {
            return gDefault.get();
        }
    ….
    ** gDefault **这是一个单例对象
        private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
            protected IActivityManager create() {
                IBinder b = ServiceManager.getService("activity");//注意这里,通过**ServiceManager**获取的字符串"activity"的IBinder
                if (false) {
                    Log.v("ActivityManager", "default service binder = " + b);
                }
                IActivityManager am = asInterface(b);
                if (false) {
                    Log.v("ActivityManager", "default service = " + am);
                }
                return am;
            }
        };
    }
    

    我们可以看到最终获取的是:IActivityManager am = asInterface(b);

    asInterface的代码:

       /**
         * Cast a Binder object into an activity manager interface, generating
         * a proxy if needed.
         */
        static public IActivityManager asInterface(IBinder obj) {
            if (obj == null) {
                return null;
            }
            //如果是不是IPC调用执行下面的代码:
            IActivityManager in =
                (IActivityManager)obj.queryLocalInterface(descriptor);
            if (in != null) {
                return in;
            }
            //如果是IPC调用执行下面的代码:
            return new ActivityManagerProxy(obj);
        }

    可以看到我们通过:return new ActivityManagerProxy(obj);
    获取到了影子的实例。
    一句话总结:ActivityManagerNative.getDefault().startService()
    最终调用的是ActivityManagerProxy 的startService()方法
    这里将有一个IPC的逻辑:
    mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
    经过Binder驱动的各种操作
    最终是运行到ActivityManagerNative的
    onTransact方法里面的。

    ActivityManagerNative->onTransact()

    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;
    }
    //省略代码
    }
    最终调用的是:
    ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);(注意这里已经不是运行在App的进程的,而是在system_Server进程中,system_Server是由Zygote进程孵化出来的。)
    在ActivityManagerNative中找不到 startService(app, service, resolvedType, callingPackage, userId);这个方法,由于ActivityManagerNative是一个抽象类,自然想到方法的实现在子类中,其实就是ActivityManagerService

    4.ActivityManagerService->startService()

        @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()方法
    mService是:
    final ActiveServices mServices;

    5.ActiveServices ->startServiceLocked

    最终调用的是

       ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
                boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
            ServiceState stracker = r.getTracker();
            if (stracker != null) {
                stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
            }
            r.callStart = false;
            synchronized (r.stats.getBatteryStats()) {
                r.stats.startRunningLocked();
            }
            //调用这个方法:
            String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
            if (error != null) {
                return new ComponentName("!!", error);
            }
    
            if (r.startRequested && addToStarting) {
                boolean first = smap.mStartingBackground.size() == 0;
                smap.mStartingBackground.add(r);
                r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
                if (DEBUG_DELAYED_SERVICE) {
                    RuntimeException here = new RuntimeException("here");
                    here.fillInStackTrace();
                    Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
                } else if (DEBUG_DELAYED_STARTS) {
                    Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
                }
                if (first) {
                    smap.rescheduleDelayedStarts();
                }
            } else if (callerFg) {
                smap.ensureNotStartingBackground(r);
            }
    
            return r.name;
        }

    startServiceInnerLocked()调用的是 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
    bringUpServiceLocked(r, service.getFlags(), callerFg, false, false)方法:
    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
    boolean whileRestarting, boolean permissionsReviewRequired)
    throws TransactionTooLargeException {
    //省略代码
    if (!isolated) {
    //注意这里获取的需要启动Service的进程的信息
    app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
    if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
    + " app=" + app);
    if (app != null && app.thread != null) {
    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) {
    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
    }

                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
        } else {
            // If this service runs in an isolated process, then each time
            // we call startProcessLocked() we will get a new isolated
            // process, starting another process if we are currently waiting
            // for a previous process to come up.  To deal with this, we store
            // in the service any current isolated process it is running in or
            // waiting to have come up.
            app = r.isolatedProc;
        }
    //省略代码
    

    }

    调用到了realStartServiceLocked()

     private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app, boolean execInFg) throws RemoteException {
    //省略代码
    这里就回到的app的进程
        app.thread.scheduleCreateService(r,r.serviceInfo,mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),app.repProcState);
     //省略代码      
    }

    最终调用ActivityThread里面的ApplicationThread->scheduleCreateService()

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

    6.由ActivityThread的内部的Handler处理 sendMessage(H.CREATE_SERVICE, s);发送的消息

    private class H extends Handler {
    public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    switch (msg.what) {
    //略
    case CREATE_SERVICE:
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
    handleCreateService((CreateServiceData)msg.obj);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    break;
    //略
    }
    }

    最终是通过反射创建一个新的Service,然后调用它的onCreate()方法

      private void handleCreateService(CreateServiceData data) {
            // If we are getting ready to gc after going to the background, well
            // we are back active so skip it.
            unscheduleGcIdler();
    
            LoadedApk packageInfo = getPackageInfoNoCheck(
                    data.info.applicationInfo, data.compatInfo);
            Service service = null;
            try {
                java.lang.ClassLoader cl = packageInfo.getClassLoader();
                service = (Service) cl.loadClass(data.info.name).newInstance();//反射创建一个新的Service
            } 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 context = ContextImpl.createAppContext(this, packageInfo);
                context.setOuterContext(service);
    
                Application app = packageInfo.makeApplication(false, mInstrumentation);
                service.attach(context, this, data.info.name, data.token, app,
                        ActivityManagerNative.getDefault());
                service.onCreate();//调用Service的onCreate()方法
                mServices.put(data.token, service);
                try {
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(service, e)) {
                    throw new RuntimeException(
                        "Unable to create service " + data.info.name
                        + ": " + e.toString(), e);
                }
            }
        }
    

    总结:

    我们可以看到其实启动一个Service的过程也是挺复杂的,由于能力所限,仅跟踪了Java Framework这一层的代码,深入到底层的就不分析了。可以参考Gityuan大神的博客。

  • 相关阅读:
    H5开发推荐使用Q.js,轻量的前端单页路由框架
    微信公众号分享接口
    ios浏览器 图片size过大(长度6000px) 设置translateZ(0)/translate3d(0,0,0),会模糊
    Android Studio创建项目
    unity 旋转两种方法
    Unity3D 物体移动方法总结
    unity3d 各键值对应代码
    MonoBehaviour简述
    unity之Rigidbody属性
    Unity UGUI实现分段式血条
  • 原文地址:https://www.cnblogs.com/bylijian/p/7372180.html
Copyright © 2020-2023  润新知