Service源码浅析一

Service源码浅析一
Service源码浅析二
Service源码浅析三
Service源码浅析四

Service类的代码量比较少,内容没什么可说的。
Service是一个抽象类。


Service

1. Start Service

    @Nullable
    public abstract ComponentName startService(Intent service);

start service其实调用的是Context的方法,Context的实现类是ContextWrapper,它的startService方法如下:

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

ContextWrapper使用代理模式,其中真正的实现类是mBase,mBase是ContextImpl的实例。
在ContextImpl中会依次调用 startService->startServiceCommon->ActivityManager.getService().startService

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

ActivityManager.getService方法如上,ActivityManager其实就是ActivityManagerService的客户端类。

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

这里用到了Singleton类,它是一个单例的工具类,在咱们得代码中也可以使用,代码我也贴一下

public abstract class Singleton<T> {

    @UnsupportedAppUsage
    public Singleton() {
    }

    @UnsupportedAppUsage
    private T mInstance;

    protected abstract T create();

    @UnsupportedAppUsage
    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

通过IActivityManagerSingleton返回了IActivityManagerSingleton的Binder对象,猜测这里发生了进程通信,详细不深究了,后边看AMS的时候补上,咱们先顺流程。
接下来就进入了ActivityManagerService进程了,调用它的startService方法。
继续走到ActiveServices的startServiceLocked,ActiveServices是ActivityManagerService的辅助类。
顺着主线继续走,ActiveServices#startServiceLocked -> startServiceInnerLocked -> bringUpServiceLocked -> bringUpServiceInnerLocked -> realStartServiceLocked
-> IApplicationThread#scheduleCreateService
走到这里有发生了一次进程通信,已经进入到对应进程里了,这里仍然疑点重重:

  1. 这里应该发生了进程创建;
  2. 如果是同一个进程怎么处理的;
    细节留到后边再补,先顺着流程走,在这之前先补个简图,方便理解。


    startService

ApplicationThread是ActivityThread的内部类,ActivityThread其实就是应用的进程入口,进程创建时会触发ActivityThread#main函数。
scheduleCreateService会向主线程的handler中发送创建服务的消息,最终调用handleCreateService,在此方法中,如果Application对象未创建,会创建Application对象并触发其onCreate方法。同时实例化Service并调用其onCreate方法。

onCreate方法执行之后咱们回到 ActiveServices#realStartServiceLocked,这里触发了IApplicationThread#scheduleCreateService之后,后边还触发了sendServiceArgsLocked,在这个方法中最终会触发r.app.getThread().scheduleServiceArgs,这里有一次进程间通信再次来到ApplicationThread。在ApplicationThread中会触发 Service#onStartCommand。

到这里Start Service流程基本结束了。

2. Bind Service

    public abstract boolean bindService(@RequiresPermission @NonNull Intent service,
            @NonNull ServiceConnection conn, int flags);

我们按照同样的方式继续分析bindService
首先来到 ContextImpl#bindServiceCommon,在这里会调用ActivityManager.getService().bindServiceInstance,这里发生了进程通信,进入AMS进程。
ActiveServices#bindServiceLocked -> bringUpServiceLocked -> bringUpServiceInnerLocked -> realStartServiceLocked
在realStartServiceLocked方法中会触发thread.scheduleCreateService来创建Service实例。
Service onCreate执行之后接下来继续执行requestServiceBindingsLocked -> r.app.getThread().scheduleBindService,又是进程通信,同样的套路触发ApplicationThread#handleBindService,然后触发Service的onBind返回一个IBinder用于进程间通信。
接下来是AMS的publishService -> ActiveServices#publishServiceLocked,最终会触发IServiceConnection#connected回调方法,这里要刹一脚车了,这个IServiceConnection是个什么东西?
这就不得不回到起点了,bindService时会传入ServiceConnection,这个参数经过LoadedApk#getServiceDispatcher -> getServiceDispatcherCommon,在这个方法中会创建ServiceDispatcher,然后又会创建InnerConnection,这个就是我们要找的IServiceConnection

        private static class InnerConnection extends IServiceConnection.Stub {
            @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
            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);
                }
            }
        }

触发它的connected,最终会调用ServiceDispatcher#connected

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

在这三个分支中都会触发doConnected,最终会调用onServiceConnected回调方法,至此bindService流程结束了。
补充一点:这里mActivityThread就是主线程的Handler,可以得出onServiceConnected最终会运行在主线程。

3. Unbind Service

public abstract void unbindService(@NonNull ServiceConnection conn);

同样执行ContextImpl#unbindService方法

    @Override
    public void unbindService(ServiceConnection conn) {
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (mPackageInfo != null) {
            IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
                    getOuterContext(), conn);
            try {
                ActivityManager.getService().unbindService(sd);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } else {
            throw new RuntimeException("Not supported in system context");
        }
    }

这里的mPackageInfo就是LoadedApk实例。
AMS#unbindService -> ActiveServices#unbindServiceLocked -> removeConnectionLocked -> ActivityThread#scheduleUnbindService -> handleUnbindService -> Service#onUnbind -> AMS#unbindFinished -> ActiveServices#unbindFinishedLocked
回到ActiveServices#removeConnectionLocked -> removeConnectionLocked -> bringDownServiceIfNeededLocked -> bringDownServiceLocked -> ActivityThread#scheduleStopService -> Service#onDestroy

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容