Android 系统服务与Binder应用服务

一、什么是系统服务及哪些是系统服务

  系统服务包括:AMS、WMS、PMS、PKMS等。

二、Binder应用服务

  什么Binder?

三、系统服务与Binder应用服务启动

  1. 系统服务启动是通过SystemServer中的run函数中启动的。

        // Start services.
        try {
            t.traceBegin("StartServices");
            startBootstrapServices(t);
            startCoreServices(t);
            startOtherServices(t);
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            t.traceEnd(); // StartServices
        }

  

  2. Bind应用服务启动

  通过ActivityThread中函数handleCreateService启动:

    @UnsupportedAppUsage
    private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

            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);
            // Service resources must be initialized with the same loaders as the application
            // context.
            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);
            }
        }
    }

 

二、注册服务

  1. 注册系统服务

    系统服务注册到ServiceManager中,通过SystemServiceRegistry.java类注册。

    比如注册AMS服务:

registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                new CachedServiceFetcher<ActivityManager>() {
            @Override
            public ActivityManager createService(ContextImpl ctx) {
                return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
            }});

  2. 注册应用服务

    应用服务是应用通过AMS与Service进行通信

Android 系统服务与Binder应用服务

 

 

Intent(this, MyService::class.java).also { intent ->
    bindService(intent, object : ServiceConnection{
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            TODO("Not yet implemented")
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            TODO("Not yet implemented")
        }

    }, Context.BIND_AUTO_CREATE)
}

  应用服务是应用通过AMS与Service绑定并获取binder对象:

  1. 应用服务调用binderService通过AMS与Service绑定,如果,应用服务未注册,首先将应用服务Service的binder对象发布到AMS中。
  2. 通过AMS将Service的binder代理对象返回给应用。
  3. 应用通过Service的binder代理对象proxy调用Service方法。

  系统服务与应用服务的注册是不同:

    • 系统服务是系统启动时通过SystemServer注册并启动的,是主动注册。
    • 应用服务是应用在获取Service的binder时,在AMS中没有对应Service的binder对象,由应用服务本身发布binder到AMS中,再由AMS将Service的binder代理对象回调给应用。应用服务是被动注册的。

三、系统服务与应用服务的使用

   1. 获取系统服务

    系统服务通过Context的getSystemService函数获取服务的对象。

val service = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager

  2. 获取应用服务binder

    通过ServiceConnection回调返回binder代理对象。

public interface ServiceConnection {
    /**
     * Called when a connection to the Service has been established, with
     * the {@link android.os.IBinder} of the communication channel to the
     * Service.
     *
     * <p class="note"><b>Note:</b> If the system has started to bind your
     * client app to a service, it's possible that your app will never receive
     * this callback. Your app won't receive a callback if there's an issue with
     * the service, such as the service crashing while being created.
     *
     * @param name The concrete component name of the service that has
     * been connected.
     *
     * @param service The IBinder of the Service's communication channel,
     * which you can now make calls on.
     */
    void onServiceConnected(ComponentName name, IBinder service);

    /**
     * Called when a connection to the Service has been lost.  This typically
     * happens when the process hosting the service has crashed or been killed.
     * This does <em>not</em> remove the ServiceConnection itself -- this
     * binding to the service will remain active, and you will receive a call
     * to {@link #onServiceConnected} when the Service is next running.
     *
     * @param name The concrete component name of the service whose
     * connection has been lost.
     */
    void onServiceDisconnected(ComponentName name);

    /**
     * Called when the binding to this connection is dead.  This means the
     * interface will never receive another connection.  The application will
     * need to unbind and rebind the connection to activate it again.  This may
     * happen, for example, if the application hosting the service it is bound to
     * has been updated.
     *
     * @param name The concrete component name of the service whose
     * connection is dead.
     */
    default void onBindingDied(ComponentName name) {
    }

    /**
     * Called when the service being bound has returned {@code null} from its
     * {@link android.app.Service#onBind(Intent) onBind()} method.  This indicates
     * that the attempting service binding represented by this ServiceConnection
     * will never become usable.
     *
     * <p class="note">The app which requested the binding must still call
     * {@link Context#unbindService(ServiceConnection)} to release the tracking
     * resources associated with this ServiceConnection even if this callback was
     * invoked following {@link Context#bindService Context.bindService() bindService()}.
     *
     * @param name The concrete component name of the service whose binding
     *     has been rejected by the Service implementation.
     */
    default void onNullBinding(ComponentName name) {
    }
}

 

  

上一篇:Android进程通信


下一篇:已获千赞,卑微打工人