Android架构之从startActivity追踪分析Android系统架构

一个成熟的应用或者系统框架应该是可以根据一角来分析出整体的;因此在Android系统方面也不例外;今天我通过追踪startActivity过程来分析一下Android的系统流程;首先我追踪到:Activity.java:

 @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

 @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }
 public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
             //重点在这里
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                    mStartedActivity = true;
            }

            final View decor = mWindow != null ? mWindow.peekDecorView() : null;
            if (decor != null) {
                decor.cancelPendingInputEvents();
            }
            } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
        if (options != null && !isTopOfTask()) {
            mActivityTransitionState.startExitOutTransition(this, options);
        }
    }

下面我们到 Instrumentation.java:

 public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            //重点在这里
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
        return null;
    }

最终执行的是ActivityManagerNative.getDefault()的startActivity方法;因此我们进入到ActivityManagerNative.java中:
首先看定义:

public abstract class ActivityManagerNative extends Binder implements IActivityManager

也就是说ActivityManagerNative 是一个Binder对象;并且实现了IActivityManager接口定义的业务;也就是说ActivityManagerNative 本身是一个实行IActivityManagerbinder;至于Binderbinder驱动有什么关系,我觉得应该是binder驱动的一个业务代理类而已。

后面进入

 private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            //获取到一个IBinde对象
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            //将其转化为IActivityManager 对象
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
从该方法可以知道,ActivityManagerNative.getDefault()也不过是将IBinder对象转化为一个IActivityManager 对象;因此我们重点关注ServiceManager.getService("activity");这句话的实现。

到ServiceManager.java中:

public static IBinder getService(String name) {
        try {
            //从缓存中获取
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                //重点看这句
                return getIServiceManager().getService(name);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }
 private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // 将BinderInternal.getContextObject()对象转化为IServiceManager 
        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }

进入到BinderInternal.java中:

 public static final native IBinder getContextObject();
 是一个本地方法;也就是说,最终的IBinder对象是从C/C++层转化而来的

我找到了对应的本地方法:
android_util_Binder.cpp文件:

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    //从自己所在的进程中获取一个sp<IBinder>对象
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    //将获取到的本地sp<IBinder>对象转化为Java层的Object对象
    return javaObjectForIBinder(env, b);
}

我们在进入ProcessState.cpp中分析一下:

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    //注意传递的参数值为0
    return getStrongProxyForHandle(0);
}


sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        // We need to create a new BpBinder if there isn't currently one, OR we
        // are unable to acquire a weak reference on this current one.  See comment
        // in getWeakProxyForHandle() for more info about this.
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            //handle==0的情况
            if (handle == 0) {
                // Special case for context manager...
                // The context manager is the only object for which we create
                // a BpBinder proxy without already holding a reference.
                // Perform a dummy transaction to ensure the context manager
                // is registered before we create the first local reference
                // to it (which will occur when creating the BpBinder).
                // If a local reference is created for the BpBinder when the
                // context manager is not present, the driver will fail to
                // provide a reference to the context manager, but the
                // driver API does not return status.
                //
                // Note that this is not race-free if the context manager
                // dies while this code runs.
                //
                // TODO: add a driver API to wait for context manager, or
                // stop special casing handle 0 for context manager and add
                // a driver API to get a handle to the context manager with
                // proper reference counting.

                Parcel data;
                //测试binder的状态
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }
            //新建一个BpBinder
            b = new BpBinder(handle); 
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            //返回
            result = b;
        } else {
            // This little bit of nastyness is to allow us to add a primary
            // reference to the remote proxy when this team doesn't have one
            // but another team is sending the handle to us.
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }
    return result;
}

仔细分析上面的过程,Java层最终获取的是C++层的一个handle==0的BpBinder对象;
回忆一下binder驱动和Service_manager的原理;我们知道,Service_manager是一个服务,是binder驱动的管家;它里面负责记录所有的其他binder_service;它通过进入一个死循环来不停读取binder驱动的消息;然后调用binder驱动的处理机制来进行消息处理;因此可以将Service_manager看做是binder驱动的发动机。而service_manager本身的句柄值就是0;因此想要获取其他binder_service要根据名字通过service_manager来查询他们的句柄值;因为service_manager中保存了所有通过binder驱动注册的进程服务;我们在Java层看到传递的name=”activity”,因此这个服务的拥有者一定是在系统启动以后,启动的一个binder_service,其中注册的一个名字是activity;
通过这个过程,我们大概可以知道Android系统是以binder驱动为核心,Service_manager为发动机的一个系统架构;里面有许多的管理各类资源的binder_service服务进程;然后当应用想要获取某一个应用进程的服务时,可以通过该进程注册的名字找到该服务,然后进程服务的调用。系统开发人员为了方便开发者调用服务,因此会利用代理模式实现好多级别的代理;最终到应用开发者这里,就可以很方便的调用系统所提供的服务接口。这就是所谓的
客户端—-binder—-服务器模式;客户端负责收集需求,收集事件数据,服务器负责真正的数据处理;binder起中介作用和资源管理分配等作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值