zoukankan      html  css  js  c++  java
  • Service启动流程

    Service启动流程从整个宏观上来看,它的模型如下

    startService启动流程时序图

    Activity中使用的startService方法是定义在Context的抽象类中,它的真正实现者是ContextImpl,所以我们首先进入ContextImpl类

    (1)ContextImpl.startService()

    frameworks/base/core/java/android/app/ContextImpl.java

    @Override
        public ComponentName startService(Intent service) {
            warnIfCallingFromSystemProcess();
            return startServiceCommon(service, mUser);
        }
    
    private ComponentName startServiceCommon(Intent service, UserHandle user) {
            try {
                validateServiceIntent(service);
                service.prepareToLeaveProcess();
                ComponentName cn = ActivityManagerNative.getDefault().startService(
                    mMainThread.getApplicationThread(), service,
                    service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
                //......
                return cn;
            } catch (RemoteException e) {
                return null;
            }
        }

    从ContextImpl类的startService开始,然后进入本类的startServiceCommon方法,并最终调用ActivityManagerNative.getDefault()对象的startService方法。其实这里的ActivityManagerNative.getDefault()就是ActivityManagerProxy对象

    (2)ActivityManagerProxy.startService()

    源码:frameworks/base/core/java/android/app/ActivityManagerNative.java

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

    通过Binder调用ActivityManagerNative类中onTransact方法,其识别码为START_SERVICE_TRANSACTION,并最终调用ActivityManagerNative的实现类ActivityManagerService的startService方法。

    (3)ActivityManagerService.startService()

    源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

        @Override
        public ComponentName startService(IApplicationThread caller, Intent service,
                String resolvedType, int userId) {
            enforceNotIsolatedCaller("startService");
            //......
            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, userId);
                Binder.restoreCallingIdentity(origId);
                return res;
            }
        }

    在这里调用mServices对象的startServiceLocked方法,这里的mServices对象是ActiveServices类。

    (4)ActiveServices.startServiceLocked()

    源码:frameworks/base/services/java/com/android/server/am/ActiveServices.java

    ComponentName startServiceLocked(IApplicationThread caller,
                Intent service, String resolvedType,
                int callingPid, int callingUid, int userId) {
    
        //......
        ServiceLookupResult res =
                retrieveServiceLocked(service, resolvedType,
                        callingPid, callingUid, userId, true, callerFg);
        ServiceRecord r = res.record;
        //......
        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    }

    相关内容,然后将解析结果放在res.record中,最后在调用startServiceInnerLocked方法。

    (5)ActiveServices.startServiceInnerLocked()

    源码:frameworks/base/services/java/com/android/server/am/ActiveServices.java

    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
                ServiceRecord r, boolean callerFg, boolean addToStarting) {
    
            //......
            synchronized (r.stats.getBatteryStats()) {
                r.stats.startRunningLocked();
            }
            String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
            //......
    }

    这里紧接着会调用bringUpServiceLocked方法。

    (6)ActiveServices.bringUpServiceLocked()

    源码:frameworks/base/services/java/com/android/server/am/ActiveServices.java

    private final String bringUpServiceLocked(ServiceRecord r,
                int intentFlags, boolean execInFg, boolean whileRestarting) {
    
        //(1)这里如果当前的ProcessRecord不为null,那就不需要重新创建进程,而是调用realStartServiceLocked方法来启动Service
        if (app != null && app.thread != null) {
                    try {
                        app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                        realStartServiceLocked(r, app, execInFg);
                        return null;
                    } 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.
                }
    
        //(2)如果是需要创建新进程,那么将调用ActivityManagerService.startProcessLocked方法来启动新进程
        if (app == null) {
                if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                        "service", r.name, false, isolated, false)) == null) {
                    //......
                    bringDownServiceLocked(r);
                    return msg;
                }
                if (isolated) {
                    r.isolatedProc = app;
                }
            }
    
        //最后将ServiceRecord保存到成员变量mPendingServices中
        if (!mPendingServices.contains(r)) {
                mPendingServices.add(r);
        }
    }

    这个方法比较重要,这里有两种选择,当Service所在的进程存在时,将调用realStartServiceLocked方法来启动Service,否则的话调用startProcessLocked方法来启动新进程。

    (7)ActivityManagerService.startProcessLocked()

    源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

    private final void startProcessLocked(ProcessRecord app, String hostingType,
                String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    
        boolean isActivityProcess = (entryPoint == null);
                if (entryPoint == null) entryPoint = "android.app.ActivityThread";
                checkTime(startTime, "startProcess: asking zygote to start proc");
                //通过processName,uid等启动新进程
                Process.ProcessStartResult startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                        app.info.dataDir, entryPointArgs);
    }

    这里通过Process的start方法启动ActivityThread的新进程,我们进入该类的main方法。

    (8)ActivityThread.main()

    源码:frameworks/base/core/java/android/app/ActivityThread.java

    public static void main(String[] args) {
            //......
    
            Process.setArgV0("<pre-initialized>");
    
            Looper.prepareMainLooper();
            //创建ActivityThread对象,并调用其attach方法
            ActivityThread thread = new ActivityThread();
            thread.attach(false);
    
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
    
            if (false) {
                Looper.myLooper().setMessageLogging(new
                        LogPrinter(Log.DEBUG, "ActivityThread"));
            }
    
            Looper.loop();
    
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    
        private void attach(boolean system) {
            final IActivityManager mgr = ActivityManagerNative.getDefault();
                try {
                    //这里调用了ActivityManagerProxy.attachApplication方法。
                    mgr.attachApplication(mAppThread);
                } catch (RemoteException ex) {
                    // Ignore
                }
        }

    在Android应用程序中,每一个进程对应一个ActivityThread实例,然后这里创建了ActivityThread对象并调用了其attach方法,在attach方法中又调用了ActivityManagerProxy.attachApplication方法。

    (9)ActivityManagerProxy.attachApplication()

    源码:frameworks/base/core/java/android/app/ActivityManagerNative.java

    public void attachApplication(IApplicationThread app) throws RemoteException
        {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IActivityManager.descriptor);
            data.writeStrongBinder(app.asBinder());
            mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
            reply.readException();
            data.recycle();
            reply.recycle();
        }

    通过Binder机制会调用ActivityManagerNative中的onTransact方法,其识别码为ATTACH_APPLICATION_TRANSACTION,并最终调用ActivityManagerService中的attachApplication方法。

    (10)ActivityManagerService.attachApplication()

    源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

    @Override
        public final void attachApplication(IApplicationThread thread) {
            synchronized (this) {
                int callingPid = Binder.getCallingPid();
                final long origId = Binder.clearCallingIdentity();
                attachApplicationLocked(thread, callingPid);
                Binder.restoreCallingIdentity(origId);
    
                //......
            }
        }

    这里调用attachApplicationLocked方法来进一步处理。

    (11)ActivityManagerService.attachApplicationLocked()

    源码:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

    private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid) {
    
        // See if the top visible activity is waiting to run in this process...
            if (normalMode) {
                try {
                    if (mStackSupervisor.attachApplicationLocked(app)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                    badApp = true;
                }
            }
    
        // Find any services that should be running in this process...
            if (!badApp) {
                try {
                //这里会调用ActiveServices对象的attachApplicationLocked方法
                    didSomething |= mServices.attachApplicationLocked(app, processName);
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                    badApp = true;
                }
            }
    }

    里如果是启动Service将调用ActiveServices对象的attachApplicationLocked方法,而如果是启动Activity将调用ActivityStackSupervisor对象的attachApplicationLocked方法。

    (12)ActiveServices.attachApplicationLocked()

    源码:frameworks/base/services/java/com/android/server/am/ActiveServices.java

    boolean attachApplicationLocked(ProcessRecord proc, String processName)
                throws RemoteException {
    
        boolean didSomething = false;
            // Collect any services that are waiting for this process to come up.
            if (mPendingServices.size() > 0) {
                ServiceRecord sr = null;
                try {
                    for (int i=0; i<mPendingServices.size(); i++) {
                        sr = mPendingServices.get(i);
                        if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                                || !processName.equals(sr.processName))) {
                            continue;
                        }
    
                        mPendingServices.remove(i);
                        i--;
                        proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,mAm.mProcessStats);
    
                        //这里调用realStartServiceLocked方法
                        realStartServiceLocked(sr, proc, sr.createdFromFg);
                        didSomething = true;
                    }
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception in new application when starting service "+ sr.shortName, e);
                    throw e;
                }
            }
        //......
    }

    (13)ActiveServices.realStartServiceLocked()

    源码:frameworks/base/services/java/com/android/server/am/ActiveServices.java

    private final void realStartServiceLocked(ServiceRecord r,
                ProcessRecord app, boolean execInFg) throws RemoteException {
    
        if (app.thread == null) {
                throw new RemoteException();
            }
    
        //......
    
        app.thread.scheduleCreateService(r, r.serviceInfo,
    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                        app.repProcState);
    }

    此处的app.thread是一个IApplicationThread对象,而IApplicationThread的代理类是ApplicationThreadProxy,我们进入app.thread对象的scheduleCreateService方法。

    (14)ApplicationThreadProxy.scheduleCreateService()

    源码:frameworks/base/core/java/android/app/ApplicationThreadNative.java

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

    通过Binder对象调用ApplicationThreadNative的onTransact方法,在其方法中调用子类的scheduleCreateService方法,即最终调用ApplicationThreadNative的子类ApplicationThread的scheduleCreateService方法。

    (15)ApplicationThread.scheduleCreateService()

    源码:frameworks/base/core/java/android/app/ActivityThread.java

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

    通过Handler发送Message来处理该操作,并进入到H的handleMessage方法中,其识别码为CREATE_SERVICE。

    (16)H.handleMessage()

    源码:frameworks/base/core/java/android/app/ApplicationThread.java

    private class H extends Handler {
    
        public void handleMessage(Message msg) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
            //这里调用handleCreateService方法
            handleCreateService((CreateServiceData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

    我们继续进入handleCreateService方法。

    (17)ApplicationThread.handleCreateService()

    源码:frameworks/base/core/java/android/app/ActivityThread.java

    private void handleCreateService(CreateServiceData data) {
    
        Service service = null;
            try {
                //(1)通过类加载器来加载Service对象
                java.lang.ClassLoader cl = packageInfo.getClassLoader();
                service = (Service) cl.loadClass(data.info.name).newInstance();
            } catch (Exception e) {
                //......
            }
    
        //(2)这里创建ContextImpl对象
        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());
        //(3)这里调用Service的onCreate方法
        service.onCreate();
        mServices.put(data.token, service);
    }

    1)处通过类加载器ClassLoader来加载Service对象,此处的data.info.name就是我们要启动的Service,加载完成后需要将其强转换为Service对象,也就是说我们的Service必须要继承于Service基类。
    (2)处这里先创建一个ContextImpl对象,每个Activity和Service都有一个Context对象。
    (3)处这里调用Service的OnCreate方法。

    好啦,到此整个Service通过startService的方式就启动起来了,接下来我们总结一下步骤。

    总结

    1、(1)-(7)从主进程调用到ActivityManagerService进程中,并调用其startProcessLocked方法来启动新的进程。
    2、(8)-(11)从新进程调用到ActivityManagerService进程中,获取要启动的服务的相关信息。
    3、(12)-(17)从ActivityManagerService进程回到新进程中并最终将服务启动起来。

  • 相关阅读:
    Java 截取目标长度英文单词字符串 要求避免截断单词
    mysql报Fatal error encountered during command execution的解决办法
    PostgreSQL 学习01 Centos7.6安装PostgreSQL10
    Ubuntu14.04 + KinectV2驱动安装 以及 Ros接口(基于网上方法试错 改进版)
    传统定位方法简介--------里程计、IMU惯性传感器以及光电编码器等
    Vue.js 动态绑定class
    MongoDB数据导入导出成csv或者json
    exception 'yiiaseErrorException' with message 'Class 'MongoClient' not found'
    exception 'DOMException' with message 'Invalid Character Error' Php + Mongodb
    浅谈Angular的 $q, defer, promise
  • 原文地址:https://www.cnblogs.com/mingfeng002/p/10592636.html
Copyright © 2011-2022 走看看