文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android Service启动绑定流程是什么

2023-07-05 10:14

关注

这篇文章主要介绍了Android Service启动绑定流程是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android Service启动绑定流程是什么文章都会有所收获,下面我们一起来看看吧。

一、Service 的启动流程

1、ContextImpl.startService

启动一个Service,通常在Activity调用startService来启动。

@Overridepublic ComponentName startService(Intent service) {    return startServiceCommon(service, false, mUser);}
2、ContextImpl.startServiceCommon

startServiceCommon检查intent内容是否合法,然后做一些离开当前进程的准备操作。调用 ActivityManager.getService()获得AMS的本地引用,并调用其startService函数。

也就是说通过Binder机制跨进程通信调用了AMSstartService函数。

private ComponentName startServiceCommon(Intent service, boolean requireForeground,        UserHandle user) {    try {        //检查intent 的compant和package是否合法        validateServiceIntent(service);        ...        ComponentName cn = ActivityManager.getService().startService(                mMainThread.getApplicationThread(), service,                service.resolveTypeIfNeeded(getContentResolver()), requireForeground,                getOpPackageName(), getAttributionTag(), user.getIdentifier());        ...        return cn;    } catch (RemoteException e) {        throw e.rethrowFromSystemServer();    }}

通过 ActivityManager.getService()的实现。

    @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;                }            };
3、AMS.startService

AMS.startService函数获取调用PidUid,然后调用ActiveServicestartServiceLocked函数。

@Overridepublic ComponentName startService(IApplicationThread caller, Intent service,        String resolvedType, boolean requireForeground, String callingPackage,        String callingFeatureId, int userId)        throws TransactionTooLargeException {    ...    synchronized(this) {        final int callingPid = Binder.getCallingPid();        final int callingUid = Binder.getCallingUid();        final long origId = Binder.clearCallingIdentity();        ComponentName res;        try {            res = mServices.startServiceLocked(caller, service,                    resolvedType, callingPid, callingUid,                    requireForeground, callingPackage, callingFeatureId, userId);        } finally {            Binder.restoreCallingIdentity(origId);        }        return res;    }}
4、ActiveService.startServiceLock

ActiveService.startServiceLock函数,对一些合法性的检查,例如前台Service的权限、限制性后台Service进行延迟运行(standby)。并将要启动的信息封装成ServiceRecord。然后调用了startServiceInnerLocked函数。

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,        int callingPid, int callingUid, boolean fgRequired, String callingPackage,        @Nullable String callingFeatureId, final int userId)        throws TransactionTooLargeException {    return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,            callingPackage, callingFeatureId, userId, false);}ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,        int callingPid, int callingUid, boolean fgRequired, String callingPackage,        @Nullable String callingFeatureId, final int userId,        boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {    final boolean callerFg;    if (caller != null) {        //获取调用Service的应用程序进程描述        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);        if (callerApp == null) {          ...        }        callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;    } else {        callerFg = true;    }    //检索ServiceRecord,包括同应用和其他应用    ServiceLookupResult res =        retrieveServiceLocked(service, null, resolvedType, callingPackage,                callingPid, callingUid, userId, true, callerFg, false, false);    ...    //要启动的ServiceRecord    ServiceRecord r = res.record;    ...    r.lastActivity = SystemClock.uptimeMillis();    r.startRequested = true;    r.delayedStop = false;    r.fgRequired = fgRequired;    r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),            service, neededGrants, callingUid));    ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);    ...    return cmp;}
5、ActiveServices.startServiceInnerLocker

调用了bringUpServiceLocked函数,会将ServiceRecord添加到ServiceMap类型的smap集合,进行缓存。

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,        boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {    r.callStart = false;    ...    String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);    ...    return r.name;}
6、 ActiveService.bringUpServiceLocked

分析一:首次启动Service时,在执行bringUpServiceLocked函数,ServiceRecord是属于新创建的,而非从AMS的缓存mServices中检索而来,所以此时的ServiceRecordProcessRecord类型appIApplicationThread类型thread都是null。只有启动过后的ServiceRecord才有值,才会执行sendServiceArgsLocked函数,重复调用Service的生命周期onStartCommand,而不调用onCreate函数。

  private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,            boolean whileRestarting, boolean permissionsReviewRequired)            throws TransactionTooLargeException {        //分析一:未启动过的ServiceRecord两者都是null,重复启动会执行该函数,        //会重复调用service的onStartCommand函数。        if (r.app != null &amp;&amp; r.app.thread != null) {            sendServiceArgsLocked(r, execInFg, false);            return null;        }...        final boolean isolated = (r.serviceInfo.flags&amp;ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;        final String procName = r.processName;        HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);        ProcessRecord app;        if (!isolated) {        ////通过AMS获取service所在进程的ProcessRecord。ProcessList=&gt;MyProcessMap=》会缓存已创建过进程的ProcessRecord            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);            if (app != null &amp;&amp; app.thread != null) {                try {                    app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);                    //启动服务                   realStartServiceLocked(r, app, execInFg);                    return null;                } catch (TransactionTooLargeException e) {                    throw e;                } catch (RemoteException e) {                    Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);                }            }        }        //如果service所在的进程未启动,通过AMS启动该进程,可以参考应用进程的启动流程          if (app == null &amp;&amp; !permissionsReviewRequired) {            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,                    hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) {;                bringDownServiceLocked(r);                return msg;            }            if (isolated) {                r.isolatedProc = app;            }        }        //等待进程启动完毕重启启动        if (!mPendingServices.contains(r)) {            mPendingServices.add(r);        }...        return null;    }
7、ActiveService.realStartServiceLocked
   private final void realStartServiceLocked(ServiceRecord r,            ProcessRecord app, boolean execInFg) throws RemoteException {        //将ProcessRecord设置给ServiceRecord        r.setProcess(app);//登记当ServiceRecord到ProcessRecordd的数组mServices,表示Service已经启动(实际未启动)        final boolean newService = app.startService(r);        boolean created = false;        try {...            app.thread.scheduleCreateService(r, r.serviceInfo,                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),                    app.getReportedProcState());          ...        } catch (DeadObjectException e) {            Slog.w(TAG, "Application dead when creating service " + r);            mAm.appDiedLocked(app, "Died when creating service");            throw e;        }         //会调用Service的onStartCommand函数         sendServiceArgsLocked(r, execInFg, true);        ...    }

通过ProcessRecord对象的IApplicationThread引用,通过Binder机制调用了应用程序的ApplicationThreadscheduleCreateService函数。

8、ApplicationThread.scheduleCreateService

ServiceInfo等相关信息封装到CreateServiceData中,并发送给ActivityThreadH类型的mH对象。

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);}
9、H.handleMesssage

调用了ActivityThreadhandleCreateService函数。

case CREATE_SERVICE:    handleCreateService((CreateServiceData)msg.obj);    break;
10、ActivityThread.handleCreateService
    private void handleCreateService(CreateServiceData data) {        ...        //获取当前应用的描述信息LoadedApk        LoadedApk packageInfo = getPackageInfoNoCheck(                data.info.applicationInfo, data.compatInfo);        Service service = null;        try {           //创建Service的上下问文           ContextImpl context = ContextImpl.createAppContext(this, packageInfo);           //获取当前应用Applcation对象            Application app = packageInfo.makeApplication(false, mInstrumentation);            //通过反射创建Service对象            java.lang.ClassLoader cl = packageInfo.getClassLoader();            service = packageInfo.getAppFactory()                    .instantiateService(cl, data.info.name, data.intent);           //初始化资源            context.getResources().addLoaders(                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));   //context 与service相互绑定            context.setOuterContext(service);            service.attach(context, this, data.info.name, data.token, app,                    ActivityManager.getService());            //调用Service的生命周期onCreate函数,意味Service创建完毕            service.onCreate();            //缓存Service            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);            }        }    }

通过ContextImpl.createAppContext创建Service的上下文context,通过packageInfo.getAppFactory().instantiateService反射获得当前Service对象service,将contextservice相互绑定。然后调用service.onCreate。至此,Service创建完毕。

二、Service的绑定

1、 ContextImpl.bindService
public boolean bindService(Intent service, ServiceConnection conn, int flags) {//系统进程调用绑定服务或发送广播都会发出警告    warnIfCallingFromSystemProcess();    return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,            getUser());}
2、ContextImpl.bindServiceCommon

在分析一,主要判断入参Executor executorUserHandle user哪个为null,总有一个为null,但最终都是调用了LoadedApkgetServiceDispatcherCommon函数来获取ServiceDispathcer类型sd。影响只是回调代码是在主线程执行,还是线程池。这里传入ActivityThreadH对象,意味着后续连接成功回调onServiceConnected是在主线程。

分析二:通过Binder机制调用AMSbindIsolatedService函数。

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,        String instanceName, Handler handler, Executor executor, UserHandle user) {    // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.    IServiceConnection sd;    if (conn == null) {        throw new IllegalArgumentException("connection is null");    }    if (handler != null && executor != null) {        throw new IllegalArgumentException("Handler and Executor both supplied");    }    if (mPackageInfo != null) {        if (executor != null) {//分析一:无论哪个分支,都是获得ServiceConnect的本地引用sd,两者最终都是        //调用LoadedApk的getServiceDispatcherCommon            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);        } else {            //正常使用走这个分支            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);        }    } else {        throw new RuntimeException("Not supported in system context");    }    //检查compant and package is null ?    validateServiceIntent(service);    try {        IBinder token = getActivityToken();        if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null                && mPackageInfo.getApplicationInfo().targetSdkVersion                < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {            flags |= BIND_WAIVE_PRIORITY;        }        service.prepareToLeaveProcess(this);        //分析二:调用AMS.bindIsolatedService        int res = ActivityManager.getService().bindIsolatedService(            mMainThread.getApplicationThread(), getActivityToken(), service,            service.resolveTypeIfNeeded(getContentResolver()),            sd, flags, instanceName, getOpPackageName(), user.getIdentifier());        if (res < 0) {            throw new SecurityException(                    "Not allowed to bind to service " + service);        }        return res != 0;    } catch (RemoteException e) {        throw e.rethrowFromSystemServer();    }}

IServiceConnection连接的创建会先从缓存中获取,避免每次都要新建。分析一:通过executorhandler创建ServiceDispatcher类型的sd,含有静态内部类InnerConnection的引用mIServiceConnection。继承自IServiceConnection.Stub,也就是InnerConnection是实现者,远程调用代理在其他进程,例如SystemServer进程中的ActiveService

private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,        Context context, Handler handler, Executor executor, int flags) {    synchronized (mServices) {        LoadedApk.ServiceDispatcher sd = null;        //从缓存获取        ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);        if (map != null) {            sd = map.get(c);        }        if (sd == null) {        //分析一:通过executor或handler创建ServiceDispatcher            if (executor != null) {                sd = new ServiceDispatcher(c, context, executor, flags);            } else {                sd = new ServiceDispatcher(c, context, handler, flags);            }            if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);            if (map == null) {                map = new ArrayMap<>();                mServices.put(context, map);            }            map.put(c, sd);        } else {            sd.validate(context, handler, executor);        }        return sd.getIServiceConnection();    }}
3、AMS.bindIsolatedService

AMS经过两次重载函数bindIsolatedService调用,简单检查相关合法性。然后调用ActiveService类型的mServicebindServiceLocked函数。

4、ActiveService.bindServiceLocked
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,        String resolvedType, final IServiceConnection connection, int flags,        String instanceName, String callingPackage, final int userId)        throws TransactionTooLargeException {    //发起绑定service的app进程描述    final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);    ...    ServiceLookupResult res =        retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,                Binder.getCallingPid(), Binder.getCallingUid(), userId, true,                callerFg, isBindExternal, allowInstant);    ...    ServiceRecord s = res.record;    ...        //描述Service和应用程序进程之间的关联,内部维护Service、进程、IntentFilter以及所有绑定信息。        AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);        //描述应用程序与service建立的一次通信(绑定)        ConnectionRecord c = new ConnectionRecord(b, activity,                connection, flags, clientLabel, clientIntent,                callerApp.uid, callerApp.processName, callingPackage);        IBinder binder = connection.asBinder();        s.addConnection(binder, c);        b.connections.add(c);        if (activity != null) {            activity.addConnection(c);        }        b.client.connections.add(c);        c.startAssociationIfNeeded();        ...        //启动Service,可以参考Service的启动        if ((flags&Context.BIND_AUTO_CREATE) != 0) {            s.lastActivity = SystemClock.uptimeMillis();            if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,                    permissionsReviewRequired) != null) {                return 0;            }        }        ...        //表示Service已启动,且已返回binder,可以通过binder访问接口        if (s.app != null && b.intent.received) {            // Service is already running, so we can immediately            // publish the connection.            try {                //建立连接                c.conn.connected(s.name, b.intent.binder, false);            } catch (Exception e) {                Slog.w(TAG, "Failure sending service " + s.shortInstanceName                        + " to connection " + c.conn.asBinder()                        + " (in " + c.binding.client.processName + ")", e);            }            //第一个绑定该Service的进程,且要重绑            if (b.intent.apps.size() == 1 && b.intent.doRebind) {                requestServiceBindingLocked(s, b.intent, callerFg, true);            }        } else if (!b.intent.requested) {//首次绑定,执行此次            requestServiceBindingLocked(s, b.intent, callerFg, false);        }        ...}

AppBindRecord 描述应用程序进程和Service的关联,包括谁绑定了ServiceProcessRecord,绑定信息IntentBindRecord,当前服务ServiceRecord,当前应用进程的所有连接记录connections

5、requestServiceBindingLocked

调用了ApplicationThreadscheduleBindService函数。

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,        boolean execInFg, boolean rebind) throws TransactionTooLargeException {           ...            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.getReportedProcState());           ...}
6、ApplicationThread.scheduleBindService

将数据封装 BindServiceData,发送个ActivityThread的H类型的mH处理。

public final void scheduleBindService(IBinder token, Intent intent,        boolean rebind, int processState) {    updateProcessState(processState, false);    BindServiceData s = new BindServiceData();    s.token = token;    s.intent = intent;    s.rebind = rebind;    sendMessage(H.BIND_SERVICE, s);}
7 、 H.handleMessage
case BIND_SERVICE:    handleBindService((BindServiceData)msg.obj);
8、ActivityThread.handleBindService

handleBindService函数有两个分支,即是否重新绑定。

如果当前进程第一个与Service绑定,且调用过了onUbBinder方法,那么这里的data.rebind将为true,直接执行ServiceonRebind函数即可。另外一种就是没有绑定过,那么需要执行ServiceonBind函数。然后还要执行AMSpublishService函数。

private void handleBindService(BindServiceData data) {    Service s = mServices.get(data.token);    if (s != null) {           ...            try {                if (!data.rebind) {                    IBinder binder = s.onBind(data.intent);                    ActivityManager.getService().publishService(                            data.token, data.intent, binder);                } else {                    s.onRebind(data.intent);                    ActivityManager.getService().serviceDoneExecuting(                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);                }            } catch (RemoteException ex) {                throw ex.rethrowFromSystemServer();            }        ...    }}
9、AMS.publishService
public void publishService(IBinder token, Intent intent, IBinder service) {    // Refuse possible leaked file descriptors    if (intent != null &amp;&amp; intent.hasFileDescriptors() == true) {        throw new IllegalArgumentException("File descriptors passed in Intent");    }    synchronized(this) {        if (!(token instanceof ServiceRecord)) {            throw new IllegalArgumentException("Invalid service token");        }        mServices.publishServiceLocked((ServiceRecord)token, intent, service);    }}
10、ActiveService.publishServiceLocked

分析一:可见在第4步bindServiceLocked函数,IntentBindRecord对象的属性binderrequestedreceived都是false

ServiceRecord的所有连接记录connections中,通过intent查找对应之前已经保存的ConnectionRecord,并调用其IServiceConnectionconnected函数。

在第2步的时候调用bindServiceCommon函数时,会创建ServiceDispatcher时,内部持有InnerConnection实例,这里的IServiceConnection代理引用指向该InnerConnection实例,这里会调用其connected函数。

    void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {        final long origId = Binder.clearCallingIdentity();        try {            if (r != null) {                Intent.FilterComparison filter                        = new Intent.FilterComparison(intent);                IntentBindRecord b = r.bindings.get(filter);                if (b != null &amp;&amp; !b.received) {//分析1                    b.binder = service;                    b.requested = true;                    b.received = true;                    ArrayMap&lt;IBinder, ArrayList&lt;ConnectionRecord&gt;&gt; connections = r.getConnections();                    for (int conni = connections.size() - 1; conni &gt;= 0; conni--) {                        ArrayList&lt;ConnectionRecord&gt; clist = connections.valueAt(conni);                        for (int i=0; i&lt;clist.size(); i++) {                            ConnectionRecord c = clist.get(i);                            if (!filter.equals(c.binding.intent.intent)) { ...                                continue;                            }                            ...                            try {                                c.conn.connected(r.name, service, false);                            } catch (Exception e) {                                Slog.w(TAG, "Failure sending service " + r.shortInstanceName                                      + " to connection " + c.conn.asBinder()                                      + " (in " + c.binding.client.processName + ")", e);                            }                        }                    }                }                serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);            }        } finally {            Binder.restoreCallingIdentity(origId);        }    }
11、InnerConnection.connected
private static class InnerConnection extends IServiceConnection.Stub {    @UnsupportedAppUsage    final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;    InnerConnection(LoadedApk.ServiceDispatcher sd) {        mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);    }    public void connected(ComponentName name, IBinder service, boolean dead)            throws RemoteException {        LoadedApk.ServiceDispatcher sd = mDispatcher.get();        if (sd != null) {            sd.connected(name, service, dead);        }    }}
12、ServiceDispatcher.connected

这里调用了 mActivityThread.post(new RunConnection(name, service, 0, dead)),执行RunConnectionrun函数。这里的话run函数执行代码又回到了应用进程的主线程。

public void connected(ComponentName name, IBinder service, boolean dead) {    if (mActivityExecutor != null) {        mActivityExecutor.execute(new RunConnection(name, service, 0, dead));    } else if (mActivityThread != null) {        mActivityThread.post(new RunConnection(name, service, 0, dead));    } else {        doConnected(name, service, dead);    }}
13、RunConnection.run

RunConnectionServiceDispatcher的内部类,这里执行SDdoConnected函数。

public void run() {    if (mCommand == 0) {        doConnected(mName, mService, mDead);    } else if (mCommand == 1) {        doDeath(mName, mService);    }}
14、ServiceDispatcher.doConnected

这里调用了ServiceConnection对象的onServiceConnected函数,也就是我们发起绑定,调用context.bindService的参数。

public void doConnected(ComponentName name, IBinder service, boolean dead) {        ...        mConnection.onServiceConnected(name, service);        ...}

到此,Service的绑定流程分析完毕。

三、Service的Context

在第一节Service的启动流程最后函数调用了ActivityThreadhandleCreateService函数。

    private void handleCreateService(CreateServiceData data) {        unscheduleGcIdler();//应用的描述信息        LoadedApk packageInfo = getPackageInfoNoCheck(                data.info.applicationInfo, data.compatInfo);        Service service = null;        try {//分析一            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);            Application app = packageInfo.makeApplication(false, mInstrumentation);            java.lang.ClassLoader cl = packageInfo.getClassLoader();            service = packageInfo.getAppFactory()                    .instantiateService(cl, data.info.name, data.intent);            context.getResources().addLoaders(                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));//分析二            context.setOuterContext(service);            //分析三            service.attach(context, this, data.info.name, data.token, app,                    ActivityManager.getService());            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);            }        }    }

分析一:通过ContextImpl的静态函数createAppContext返回了一个ContextImpl类型的contextcreateAppContext又调用了重载函数createAppContext。直接新建了ContextImpl实例context,构造函数传递了ActivityThread类型的mainThread和LoadedApk类型的packageInfo。并给context设置了资源环境和是否Syetem属性。

static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {    return createAppContext(mainThread, packageInfo, null);}static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,        String opPackageName) {    if (packageInfo == null) throw new IllegalArgumentException("packageInfo");    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, null,            0, null, opPackageName);    context.setResources(packageInfo.getResources());    context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context);    return context;}

ContextImpl类有一个Context类型的mOuterContext属性,在构造函数时指向了自己。

回到handleCreateService函数的分析二,在创建好Service对象service之后,将service作为参数传递给了context.setOuterContext函数。Service本身继承自ContextWrapper,ContextWrapper又是Context的子类。这时候的setOuterContext函数将service设置给了contextmOuterContext属性。意味着当前上下文context持有当前新建的service引用。

在分析三,调用了service.attach函数,context并作为第一个参数被传入。attach函数又调用了attachBaseContext函数。

public final void attach(        Context context,        ActivityThread thread, String className, IBinder token,        Application application, Object activityManager) {    attachBaseContext(context);    mThread = thread;     mClassName = className;    mToken = token;    mApplication = application;    mActivityManager = (IActivityManager)activityManager;    mStartCompatibility = getApplicationInfo().targetSdkVersion            &lt; Build.VERSION_CODES.ECLAIR;    setContentCaptureOptions(application.getContentCaptureOptions());}

attachBaseContext调用了父类ContextWrapperattachBaseContext函数

@Overrideprotected void attachBaseContext(Context newBase) {    super.attachBaseContext(newBase);    if (newBase != null) {        newBase.setContentCaptureOptions(getContentCaptureOptions());    }}

ContextWrapper将一路传递过来的上下文base设置给你了mBase属性。

protected void attachBaseContext(Context base) {    if (mBase != null) {        throw new IllegalStateException("Base context already set");    }    mBase = base;}

也就是说,我们在启动Service时,会同时创建Service的上下文context,并将其存储到Service的父类ContextWrappermBases属性中,同时context也会有当前Service引用,存储在mOuterContext变量中。

关于“Android Service启动绑定流程是什么”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Android Service启动绑定流程是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯