Android Framework(四)--系统服务与bind的应用服务的区别

目录

启动方式

注册方式

使用方式


启动方式

系统服务

在SystemServer里面进行分批、分阶段启动,大部分都跑在binder线程里面。

应用服务

private ComponentName startServiceCommon(Intent service, boolean requireForeground,UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            //版本的不同,启动对象有不同,这里是Android 9
            ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), 
                service, 
                service.resolveTypeIfNeeded(getContentResolver()), 
                requireForeground,getOpPackageName(),
                user.getIdentifier()
                );
            if (cn != null) {
                if (cn.getPackageName().equals("!")) {
                    throw new SecurityException(
                            "Not allowed to start service " + service
                            + " without permission " + cn.getClassName());
                } else if (cn.getPackageName().equals("!!")) {
                    throw new SecurityException(
                            "Unable to start service " + service
                            + ": " + cn.getClassName());
                } else if (cn.getPackageName().equals("?")) {
                    throw new IllegalStateException(
                            "Not allowed to start service " 
                            + service + ": " 
                            + cn.getClassName());
                    }
                }
                return cn;
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
    }

通过ActivityManager.getService().startService()启动的,后面会跟到源码ActiveServices这里:

// 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 会调用到客户端的 ActivityThread 中:

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

很熟悉的sendMessage方法,会发送消息到H类里面:

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

    }

跟入handleCreateService((CreateServiceData)msg.obj)方法:

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;

        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        //获取service对象
        service = packageInfo.getAppFactory()
                .instantiateService(cl, data.info.name, data.intent);
        
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);

        Application app = packageInfo.makeApplication(false, mInstrumentation);
        //将上下文赋予service
        service.attach(context, this, data.info.name, data.token, app,
                ActivityManager.getService());
        //执行service回调
        service.onCreate();
        mServices.put(data.token, service);
        ActivityManager.getService().serviceDoneExecuting(
                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);

    }

分开看,instantiateService用来构建Service对象,attach给service赋予application,最后调用onCreate方法。

注册方式

系统服务

总体上无论SysteServer、还是单独进程,都是要注册到ServiceManager上的。

补充:只有系统服务才能注册在ServiceManager, 

应用服务

  1. 应用端会向AMS发起bindService。
  2. AMS会先判断这个Service是否已经注册过了,注册过就直接把之前发布的binder返回给应用;如果没有,AMS会像Service请求binder对象。(AMS请求的,属于被动注册)
  3. Service会相应AMS的请求,发布这个binder对象到AMS
  4. AMS再把这个binder对象回调给应用

使用方式

系统服务

通过服务名去找到对于的ServiceFetcher对象,然后先通过SM.getService拿到binder对象,然后封装了一层拿到服务的管理对象。

应用服务

通过bindService向AMS发送绑定服务端请求,AMS通过onServiceConnected()回调把服务的binder对象返回给业务端,然后把这个对象封装成业务接口对象给业务接口调用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值