广告位联系
返回顶部
分享到

Android Service启动绑定流程介绍

Android 来源:互联网 作者:佚名 发布时间:2023-03-10 21:27:14 人浏览
摘要

本文基于Android 11,参考《Android进阶解密》一书资料。了解Service的启动和绑定流程,以及Service的Context创建过程。 由于基于分析流程,忽略很多细节分支。各位在看源码的时候,要尽可

本文基于Android 11,参考《Android进阶解密》一书资料。了解Service的启动和绑定流程,以及Service的Context创建过程。

由于基于分析流程,忽略很多细节分支。各位在看源码的时候,要尽可能忽略细节,分析整体流程之后,还有精力的话再去看细节。例如有些属性是在后面赋值的,如果在前面追究,难哦。

另:阅读这种流程需要很大的耐心和毅力。建议在心情愉悦想要学习的时候搭配源码一起食用。

一、Service 的启动流程

1、ContextImpl.startService

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

1

2

3

4

@Override

public ComponentName startService(Intent service) {

    return startServiceCommon(service, false, mUser);

}

2、ContextImpl.startServiceCommon

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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()的实现。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@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函数获取调用Pid和Uid,然后调用ActiveService的startServiceLocked函数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

@Override

public 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函数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

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集合,进行缓存。

1

2

3

4

5

6

7

8

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中检索而来,所以此时的ServiceRecord的ProcessRecord类型app和IApplicationThread类型thread都是null。只有启动过后的ServiceRecord才有值,才会执行sendServiceArgsLocked函数,重复调用Service的生命周期onStartCommand,而不调用onCreate函数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

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机制调用了应用程序的ApplicationThread的scheduleCreateService函数。

8、ApplicationThread.scheduleCreateService

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

1

2

3

4

5

6

7

8

9

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

调用了ActivityThread的handleCreateService函数。

1

2

3

case CREATE_SERVICE:

    handleCreateService((CreateServiceData)msg.obj);

    break;

10、ActivityThread.handleCreateService

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

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,将context与service相互绑定。然后调用service.onCreate。至此,Service创建完毕。

二、Service的绑定

1、 ContextImpl.bindService

1

2

3

4

5

6

public boolean bindService(Intent service, ServiceConnection conn, int flags) {

    //系统进程调用绑定服务或发送广播都会发出警告

    warnIfCallingFromSystemProcess();

    return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,

            getUser());

}

2、ContextImpl.bindServiceCommon

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

分析二:通过Binder机制调用AMS的bindIsolatedService函数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

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类型的mService的bindServiceLocked函数。

4、ActiveService.bindServiceLocked

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

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的关联,包括谁绑定了Service的ProcessRecord,绑定信息IntentBindRecord,当前服务ServiceRecord,当前应用进程的所有连接记录connections。

5、requestServiceBindingLocked

调用了ApplicationThread的scheduleBindService函数。

1

2

3

4

5

6

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处理。

1

2

3

4

5

6

7

8

9

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

1

2

case BIND_SERVICE:

    handleBindService((BindServiceData)msg.obj);

8、ActivityThread.handleBindService

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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

1

2

3

4

5

6

7

8

9

10

11

12

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对象的属性binder、requested、received都是false。

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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)),执行RunConnection的run函数。这里的话run函数执行代码又回到了应用进程的主线程。

1

2

3

4

5

6

7

8

9

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

RunConnection是ServiceDispatcher的内部类,这里执行SD的doConnected函数。

1

2

3

4

5

6

7

public void run() {

    if (mCommand == 0) {

        doConnected(mName, mService, mDead);

    } else if (mCommand == 1) {

        doDeath(mName, mService);

    }

}

14、ServiceDispatcher.doConnected

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

1

2

3

4

5

public void doConnected(ComponentName name, IBinder service, boolean dead) {

        ...

        mConnection.onServiceConnected(name, service);

        ...

}

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

三、Service的Context

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

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类型的context。createAppContext又调用了重载函数createAppContext。直接新建了ContextImpl实例context,构造函数传递了ActivityThread类型的mainThread和LoadedApk类型的packageInfo。并给context设置了资源环境和是否Syetem属性。

1

2

3

4

5

6

7

8

9

10

11

12

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设置给了context的mOuterContext属性。意味着当前上下文context持有当前新建的service引用。

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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调用了父类ContextWrapper的attachBaseContext函数

1

2

3

4

5

6

7

@Override

protected void attachBaseContext(Context newBase) {

    super.attachBaseContext(newBase);

    if (newBase != null) {

        newBase.setContentCaptureOptions(getContentCaptureOptions());

    }

}

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

1

2

3

4

5

6

protected void attachBaseContext(Context base) {

    if (mBase != null) {

        throw new IllegalStateException("Base context already set");

    }

    mBase = base;

}

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

总结

  • Service的启动和绑定从AMS转移到ActiveService
  • Service的启动,会先判断进程是否创建,提前启动进程,再启动自己。
  • Service重复启动,会重复调用onStratCommand及后续生命周期函数。
  • Service的绑定,会先走一趟Service的启动流程,再绑定。
  • 应用进程与SytemServer进程(AMS、ActiveService)的交互式通过Binder机制进行,通过AIDL各持有双方接口。应用进程通过H对象,将现成重新切回主线程(所有应用夸进程通信应如此)。
  • Service在应用和AMS两边都会做缓存,以便快速在找到使用。应用程序存储在ArrayMap<IBinder, Service>类型的mServices;ActiveService则是ArraySet<ServiceRecord>类型的mServices。

版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://juejin.cn/post/7208005892302176317
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计