学习android内核 -- Activity启动过程

来源:互联网 发布:购买网络电视 编辑:程序博客网 时间:2024/06/13 01:11

首先我们最常见的activity都是最终继承自Context,很多的实现并不是完全在acitivty.java中实现的。

 

比如我们常见的启动一个activity-〉startActivity(),有两种

1.我们常见的在activity中做的调转是调用activity中的startActivity();


2.mContext.startActivity则一般是调用的是ContextImpl的startActivity() (而ContextImpl的创建是在ActivityThread中完成的)。该mContext是指从系统进程中创建的Context对象


它们共同都是调用Instrumentation的execStartActivity()



如:

ActivityThread->performLaunchActivity()中有一端对ContextImpl进行了创建以及传递了引用,

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {............
if (activity != null) {                ContextImpl appContext = new ContextImpl();                appContext.init(r.packageInfo, r.token, this);                appContext.setOuterContext(activity);                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());                Configuration config = new Configuration(mCompatConfiguration);                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "                        + r.activityInfo.name + " with config " + config);                activity.attach(appContext, this, getInstrumentation(), r.token,                        r.ident, app, r.intent, r.activityInfo, title, r.parent,                        r.embeddedID, r.lastNonConfigurationInstances, config);                if (customIntent != null) {                    activity.mIntent = customIntent;                }.............
        } catch (SuperNotCalledException e) {            throw e;        } catch (Exception e) {            if (!mInstrumentation.onException(activity, e)) {                throw new RuntimeException(                    "Unable to start activity " + component                    + ": " + e.toString(), e);            }        }        return activity;}


 

 

 

其它的如ContextWrapper只是对Context的一重包装,一个包装过的类,它里面必须要包含一个真正的Context引用;ContextWrapper中提供了attachBaseContext()来指定真正的context对象,调用ContextWrapper的方法都会被转向其所包含的真正的Context对象。

 

 

 ContextImpl:

 @Override    public void startActivity(Intent intent) {        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {            throw new AndroidRuntimeException(                    "Calling startActivity() from outside of an Activity "                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."                    + " Is this really what you want?");        }        mMainThread.getInstrumentation().execStartActivity(            getOuterContext(), mMainThread.getApplicationThread(), null,            (Activity)null, intent, -1);    }


 

主要是通过getInstrumentation().execStartActivity这个方法里去调用的,那么我们现在来看execStartActivity()这个方法。

它在叫Instrumentation.java这个类中:

public ActivityResult execStartActivity(            Context who, IBinder contextThread, IBinder token, Activity target,            Intent intent, int requestCode) {        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.setAllowFds(false);
//从这里可以看出是调用了本地方法,进行对activity进行启动的
            int result = ActivityManagerNative.getDefault()                .startActivity(whoThread, intent,                        intent.resolveTypeIfNeeded(who.getContentResolver()),                        null, 0, token, target != null ? target.mEmbeddedID : null,                        requestCode, false, false, null, null, false);            checkStartActivityResult(result, intent);        } catch (RemoteException e) {        }        return null;    }


从上面的代码可以看出,是由本地方法对activity进行了启动。