Android-10-四大组件-系列-Service-的-启动流程

1次阅读

共计 12101 个字符,预计需要花费 31 分钟才能阅读完成。

前言

因为源码剖析的代码量比拟大,大部分博客网站的内容显示页面都比拟窄,显示进去的成果都异样俊俏,所以您也能够间接查看《Thinking in Android》来浏览这边文章,心愿这篇文章能帮你梳理分明 “Service 的启动流程”

外围源码

要害类 门路
ContextImpl.java frameworks/base/core/java/android/app/ContextImpl.java
ContextWrapper.java frameworks/base/core/java/android/content/ContextWrapper.java
ContextThemeWrapper.java frameworks/base/core/java/android/view/ContextThemeWrapper.java
Activity.java frameworks/base/core/java/android/app/Activity.java
ActivityManager.java frameworks/base/core/java/android/app/ActivityManager.java
ActivityManagerService.java frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
ActiveServices.java frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
ActivityThread.java frameworks/base/core/java/android/app/ActivityThread.java

Service 的启动过程绝对 Activity 的启动过程来说简略了很多,咱们都晓得怎么去创立和启动一个 Service,那么你有没有从源码角度钻研过 Service 启动后在零碎层是如何运作的

Activity.startService()

首先咱们晓得:要启动一个 Service 的时候,个别都是在 Activity 中通过 startService() 来启动:

Intent intent = new Intent(MainActivity.this, xxxService.class);
startService(intent);

然而咱们在 Activity 源码中并没有实现 startService() 办法,那它在哪里被调用的?找不到咱们就去 Activity 的父类中找。

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

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback, WindowControllerCallback,
        AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient { }

// frameworks/base/core/java/android/view/ContextThemeWrapper.java

public class ContextThemeWrapper extends ContextWrapper {

}

// frameworks/base/core/java/android/content/ContextWrapper.java
public class ContextWrapper extends Context {}

Activity 继承了 ContextThemeWrapper 类,ContextThemeWrapper 又继承了 ContextWrapper 类,ContextWrapper 又继承了 Context 类。

ContextWrapper.startService()

ContextWrapper 中实现了 startService() 办法:

// frameworks/base/core/java/android/content/ContextWrapper.java

public class ContextWrapper extends Context {

    Context mBase;

    public ContextWrapper(Context base) {mBase = base;}

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

}

所以 startService() 办法其实是由 ContextWrapper 实现的,紧接着又调用了 mBase.startService() 办法,mBase 对象是 Context 的子类 ContextImpl,所以调用最终进入 ContextImpl 类的 startService() 办法。

ContextImpl.startService()

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

class ContextImpl extends Context {

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

    private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) {
        try {validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            // 通过 Binder 过程间通信进入 ActivityManagerService 的 startService() 办法
            ComponentName cn = ActivityManager.getService().startService(mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), requireForeground, getOpPackageName(), user.getIdentifier());
            ... ...

            return cn;
        } catch (RemoteException e) {throw e.rethrowFromSystemServer();
        }
    }

}

ActivityManager.getService()

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

public class ActivityManager {

    @UnsupportedAppUsage
    public static IActivityManager getService() {return IActivityManagerSingleton.get();
    }

    @UnsupportedAppUsage
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

}

ActivityManagerService.startService()

接下来就执行到 ActivityManagerServicestartService() 办法:

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

    final ActiveServices mServices;

    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage, int userId)
            throws TransactionTooLargeException {
        ... ...

        synchronized(this) {final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res;
            try {// 调用 ActiveServices 的 startServiceLocked() 办法
                res = mServices.startServiceLocked(caller, service, resolvedType, callingPid,
                            callingUid, requireForeground, callingPackage, userId);
            } finally {Binder.restoreCallingIdentity(origId);
            }
            return res;
        }
    }

}

ActiveServices.startServiceLocked()

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

public final class ActiveServices {

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
            throws TransactionTooLargeException {
        return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
                callingPackage, userId, false);
    }

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage,
            final int userId, boolean allowBackgroundActivityStarts)
            throws TransactionTooLargeException {
        ... ...
        
        // 解析 AndroidManifest.xml 文件中配置 Service 的 intent-filter 相干内容信息
        ServiceLookupResult res = retrieveServiceLocked(service, null, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false, false);
        if (res == null) {return null;}
        ... ...

        ServiceRecord r = res.record;
        ... ...

        // 调用 startServiceInnerLocked() 办法
        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
        return cmp;
    }

}

通过 retrieveServiceLocked() 办法来解析 AndroidManifest.xml 文件中配置 Service 的 intent-filter 相干内容信息。

当解析完 Serviceintent-filter 相干内容信息后,解析的后果会保留在 res.record 变量中。而 res 变量是一个 ServiceLookupResult 类型的对象,它的 record 变量则是一个 ServiceRecord 类型对象,用来示意一个 Service

ActiveServices.startServiceInnerLocked()

ActiveServices 的 startServiceLocked() 办法最初调用了 startServiceInnerLocked() 办法:

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

public final class ActiveServices {

    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
        ... ...

        // 调用 bringUpServiceLocked() 办法
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
        ... ...

    }
}

ActiveServices.bringUpServiceLocked()

调用 bringUpServiceLocked() 办法进一步解决:

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

public final class ActiveServices {

    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
        ... ...

        ProcessRecord app;

        if (!isolated) {app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);    // 获取 app 对象
            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.longVersionCode, mAm.mProcessStats);
                    // 运行 service 的过程曾经启动,调用 realStartServiceLocked() 办法
                    realStartServiceLocked(r, app, execInFg);
                    return null;
                } catch (TransactionTooLargeException e) {throw e;} catch (RemoteException e) {Slog.w(TAG, "Exception when starting service" + r.shortInstanceName, e);
                }

                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
        } else {... ...}

        // Not running -- get it started, and enqueue this service record
        // to be executed when the app comes up.
        if (app == null && !permissionsReviewRequired) {
            if ((app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingRecord, false, isolated, false)) == null) {
                String msg = "Unable to launch app"
                        + r.appInfo.packageName + "/"
                        + r.appInfo.uid + "for service"
                        + r.intent.getIntent() + ": process is bad";
                Slog.w(TAG, msg);
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {r.isolatedProc = app;}
        }
        ... ...

        return null;
    }

}

bringUpServiceLocked() 办法首先通过 getProcessRecordLocked() 办法去获取 app 对象,它是一个 ProcessRecord 类型的对象,如果它不为空,阐明 Service 要运行的过程曾经存在。

Service 运行的过程有两种:

(1)一种是默认的,即运行在 Activity 启动 Service 的那个过程里,也就是说在哪个过程里调用了 startService() 办法,启动的 service 就运行在哪个过程里。

(2)一种是给 Service 一个独自的过程运行,比方在 AndroidManifest 文件里配置了如下内容:

//

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.documentsui">

    <application
        android:name=".DocumentsApplication"
        android:label="@string/app_label"
        android:icon="@drawable/app_icon"
        android:supportsRtl="true"
        android:allowBackup="true"
        android:backupAgent=".prefs.BackupAgent"
        android:fullBackupOnly="false">

        <!-- Run FileOperationService in a separate process so that we can use FileLock class to
            wait until jumbo clip is done writing to disk before reading it. See ClipStorage for
            details. -->
        <service
            android:name=".services.FileOperationService"
            android:exported="false"
            android:process=":com.android.documentsui.services">
        </service>

    </application>
</manifest>

在这段配置里有 android:process="xxx" 申明,这个申明用来实现 service 独自运行在 “xxx” 过程里。这样做的益处是,即便应用程序无奈工作,因为 service 独自运行在一个过程里,所以会持续工作

回到后面的办法,如果变量 app 为空,就代表 service 要运行的过程还没有启动,于是调用 startProcessLocked() 办法去启动一个新的过程。

如果 app 不为空,采纳默认的形式启动 Service,最终调用到 realStartServiceLocked() 办法:

ActiveServices.realStartServiceLocked()

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

public final class ActiveServices {

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        ... ...

        try {
            ... ...

            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo), app.getReportedProcState());
            ... ...

        }
        ... ...

    }

}

在这个办法中,app 对象的 thread 变量是一个 ApplicationThread Binder 对象,调用它的 scheduleCreateService() 办法之后,会进入客户端的 ActivityThread 中。

ActivityThread.scheduleCreateService()

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

public final class ActivityThread extends ClientTransactionHandler {

    // ApplicationThread 是一个 Binder
    private class ApplicationThread extends IApplicationThread.Stub {

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

    }
    
}

ApplicationThreadscheduleCreateService() 办法通过调用 sendMessage() 办法来发送一个 msg 音讯,当 Handler 接管到了 msg 音讯之后,它会调用 handleCreateService() 办法来做进一步解决。

H.handleMessage()

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

public final class ActivityThread extends ClientTransactionHandler {

    class H extends Handler {public void handleMessage(Message msg) {switch (msg.what) {

                case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate:" + String.valueOf(msg.obj)));
                    handleCreateService((CreateServiceData)msg.obj);    // 调用 handleCreateService() 办法
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

            }
        }

    }
}

ActivityThread.handleCreateService()

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

public final class ActivityThread extends ClientTransactionHandler {private void handleCreateService(CreateServiceData data) {
        ... ...

        LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);
        } 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, ActivityManager.getService());
            service.onCreate();    // 进入 Service.onCreate() 办法
            mServices.put(data.token, service);
            try {ActivityManager.getService().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);
            }
        }
    }

}

ActivityThread 类的 handleCreateService() 办法中,首先通过 ClassLoader 类把 Service 加载进来,而参数 data.info.name 示意这个 Service 的名字,instantiateService() 办法是创立一个 Service 实例。接着,创立一个 Context 对象,作为上下文环境之用。

handleCreateService() 办法最初调用了 service 的 onCreate() 办法 ,当这个办法被调用之后, 就会进入应用程序里 Service 的 onCreate() 办法

至此,Service 的启动就剖析结束,这个过程与启动 Activity 相比简略了很多。

正文完
 0