Binder Framework 层(基于android 12.0/S)

Binder在Fwk层通过JNI访问到Binder Native的框架,并且主要的操作是交由Binder Native进行处理的。

Bp:BinderProxy 代理肯定是client端

Bn: BinderNative native是server端

Binder 服务的启动是由zygote进程调用AndroidRuntime.cpp 中的startReg 通过JNI进行注册的,本文主要侧重FWK层的其他流程,Binder启动过程可以参考一下其他的博客。

Fwk层的ServiceManager位于:

/frameworks/base/core/java/android/os/ServiceManager.java

添加服务:

ServiceManager 类中一共有三个重载的addService方法

 

最终都会附加参数调用到下面的方法: 

前两个重载方法中的DUMP_FLAG_PRIORITY_DEFAULT 是dump的级别,这里采用默认级别即可。 

addService中 首先通过getIServiceManager获取到ServiceManager的代理,然后执行addService方法将服务添加到ServiceManager的管理中。

getIServiceManager

 

拆解如下:

BinderInternal.getContextObject()

通过JNI 调用到 android_util_Binder中的方法,实现了Java到C++的转换。(需要再梳理下JNI的知识) 

Process::self()->getContextObject 这块在Android Binder 之 ServiceManager 文章中有拆解

getContextObject最终会返回serviceManager的BpBinder对象。然后通过JavaObjectForIBinder()根据C++的BpBinder生成Java的BinderProxy对象。

// If the argument is a JavaBBinder, return the Java object that was used to create it.// Otherwise return a BinderProxy for the IBinder. If a previous call was passed the// same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
    jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val){
    // N.B. This function is called from a @FastNative JNI method, so don't take locks around// calls to Java code or block the calling thread for a long time for any reason.
    if (val == NULL) return NULL;
    //已经有Java 对象了,直接返回
    if (val->checkSubclass(&gBinderOffsets)) {
        // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
        jobject object = static_cast<JavaBBinder*>(val.get())->object();
        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
        return object;
    }

    BinderProxyNativeData* nativeData = new BinderProxyNativeData();
    nativeData->mOrgue = new DeathRecipientList;
    nativeData->mObject = val;

    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
    if (env->ExceptionCheck()) {
        // In the exception case, getInstance still took ownership of nativeData.return NULL;
    }
    BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
    if (actualNativeData == nativeData) {
        // Created a new Proxy
        uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
        uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
        if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
            // Multiple threads can get here, make sure only one of them gets to// update the warn counter.if (gProxiesWarned.compare_exchange_strong(numLastWarned,
                        numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
                ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
            }
        }
    } else {
        delete nativeData;
    }
    return object;
}

 ServiceManagerNative.asInterface:

将 Binder 对象转换成 IServiceManager对象

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {        
        mRemote = remote;
        mServiceManager = IServiceManager.Stub.asInterface(remote);
    }
    public IBinder asBinder() {        return mRemote;
    }

    @UnsupportedAppUsage   
  public IBinder getService(String name) throws RemoteException{ 
     // Same as checkService (old versions of servicemanager had both methods).
     return mServiceManager.checkService(name);
   }
  public IBinder checkService(String name) throws RemoteException{        
    return mServiceManager.checkService(name);
 }
    public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)            throws RemoteException {
        mServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }
    public String[] listServices(int dumpPriority) throws RemoteException {       
     return mServiceManager.listServices(dumpPriority);
    }
    public void registerForNotifications(String name, IServiceCallback cb)            throws RemoteException {
        throw new RemoteException();
    }
    public void unregisterForNotifications(String name, IServiceCallback cb)            throws RemoteException {
        throw new RemoteException();
    }
    public boolean isDeclared(String name) throws RemoteException {        return mServiceManager.isDeclared(name);
    }
    public String[] getDeclaredInstances(String iface) throws RemoteException {      
      return mServiceManager.getDeclaredInstances(iface);
    }
    public String updatableViaApex(String name) throws RemoteException {        
    return mServiceManager.updatableViaApex(name);
    }
    public void registerClientCallback(String name, IBinder service, IClientCallback cb)            throws RemoteException {
        throw new RemoteException();
    }
    public void tryUnregisterService(String name, IBinder service) throws RemoteException {       
     throw new RemoteException();
    }
    public ServiceDebugInfo[] getServiceDebugInfo() throws RemoteException {        
    return mServiceManager.getServiceDebugInfo();
    }
    /**
     * Same as mServiceManager but used by apps.
     *
     * Once this can be removed, ServiceManagerProxy should be removed entirely.
     */
    @UnsupportedAppUsageprivate IBinder mRemote;
    private IServiceManager mServiceManager;
}

 ServiceManagerNative.asInterface = new ServiceManagerProxy(),所以梳理一下获取服务的接口 getIServiceManager 就等于 new ServiceManagerProxy(new BinderProxy(BpBinder(0))),所以最后就拿到了native ServiceManager的代理。

继续看addService方法的拆解,下图是serviceManagerProxy中的addService方法:

其中mServiceManager是在构造方法中设置的: 

获取服务: 

sCache中记录了常见的服务的信息,在ActivityThread的bindApplication 中调用initServiceCache进行了初始化操作。 

 

 

如果sCache中并没有我们想要找的service,那么会通过Binder.allowBlocking(rawGetService()) 获取到服务的IBinder对象

    private static IBinder rawGetService(String name) throws RemoteException {        
        final long start = sStatLogger.getTime();

       //通过BpBinder(0).getService去获取IBinder对象
        final IBinder binder = getIServiceManager().getService(name);

        final int time = (int) sStatLogger.logDurationStat(Stats.GET_SERVICE, start);

        final int myUid = Process.myUid();
        final boolean isCore = UserHandle.isCore(myUid);

        //getService的数据统计,性能分析打点
        final long slowThreshold = isCore
                ? GET_SERVICE_SLOW_THRESHOLD_US_CORE
                : GET_SERVICE_SLOW_THRESHOLD_US_NON_CORE;

        synchronized (sLock) {
            sGetServiceAccumulatedUs += time;
            sGetServiceAccumulatedCallCount++;

            final long nowUptime = SystemClock.uptimeMillis();

            // Was a slow call?if (time >= slowThreshold) {
                // We do a slow log:// - At most once in every SLOW_LOG_INTERVAL_MS// - OR it was slower than the previously logged slow call.
                if ((nowUptime > (sLastSlowLogUptime + SLOW_LOG_INTERVAL_MS))
                        || (sLastSlowLogActualTime < time)) {
                    EventLogTags.writeServiceManagerSlow(time / 1000, name);

                    sLastSlowLogUptime = nowUptime;
                    sLastSlowLogActualTime = time;
                }
            }

            // Every GET_SERVICE_LOG_EVERY_CALLS calls, log the total time spent in getService().final int logInterval = isCore
                    ? GET_SERVICE_LOG_EVERY_CALLS_CORE
                    : GET_SERVICE_LOG_EVERY_CALLS_NON_CORE;

            if ((sGetServiceAccumulatedCallCount >= logInterval)
                    && (nowUptime >= (sLastStatsLogUptime + STATS_LOG_INTERVAL_MS))) {

                EventLogTags.writeServiceManagerStats(
                        sGetServiceAccumulatedCallCount, // Total # of getService() calls.
                        sGetServiceAccumulatedUs / 1000, // Total time spent in getService() calls.
                        (int) (nowUptime - sLastStatsLogUptime)); // Uptime duration since last log.
                sGetServiceAccumulatedCallCount = 0;
                sGetServiceAccumulatedUs = 0;
                sLastStatsLogUptime = nowUptime;
            }
        }
        return binder;
    }

android 8.0.0_r36 之前都是如下结构,没有通过rawGetService方法,而是直接在getService中通过return getIServiceManager().getService(name);获取到Ibinder对象。

FWK 应用实例:

addService:

开机过程中在init 进程启动zygote 以后,zygote会通过fork操作创建出systemServer进程,PackageManagerService 就是systemSever中一个比较重要的线程。PackageManagerService 启动流程中会调用其中的main方法并在main方法中以“package”和“package_native”为名将PackageManagerService 和PackageManagerServiceNative添加到ServiceManager的管理中去。

值得一提的是 ,因为Fwk层的ServiceManager类是final的,所以不需要创建实例就可以直接调用类中方法。

 

getService:

 

 

千里马8年Android系统及应用开发经验,曾担任过美国unokiwi公司移动端技术总监兼架构师,对系统开发,性能优化,应用高级开发有深入的研究,Android开源定制ROM Lineage的贡献者之一,国内首家线下开辟培训Android Framework课程,拥有2年的Android系统培训经验。成为腾讯课堂专业负责android framework课程分享第一人,致力于提高国内android Framework水平Android Framework领域内是国内各大手机终端科技公司需要的人才,应用开发者都对Android系统充满着好奇,其中的binder是重中之重,都说无binderAndroidbinde是Android系统的任督二脉。课程水平循序渐进,由中级再到高级,满足各个次水平的android开发者。1、灵活使用binder跨进程通信,在app端对它的任何api方法等使用自如2、可以单独分析android系统源码中任何binder部分,分析再也没有难度3、掌握binder驱动本质原理,及对应binder驱动怎么进行跨进程通信,及内存等拷贝方式数据等4、对binder从上的java app端一直到最底的内核binder驱动,都可以顺利理通5、针对系统开发过程中遇到的binder报错等分析方法,及binder bug案例学习6、针对面试官任何的binder问题都可以对答自如7、socket这种跨进程通信实战使用8、针对android源码中使用的socket源码轻松掌握9、android系统源码中最常见的socketpair中双向跨进程通信10、使用socket实现一个可以让app执行shell命令的程序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值